Как реализовать глобальное действие MVC

Я работаю над добавлением глобализации/локализации в довольно масштабное приложение. Все завершено, кроме самих просмотров. Пока что мой подход заключается в добавлении глобального действия, которое может вызывать каждое представление для получения локализованных строк. У меня проблема в том, что я не могу создать такое глобальное действие.

Пока я добавил action к моей обычной controller... и я могу ударить, и все работает. Однако, когда я перемещаю этот метод в BaseController, действие больше не срабатывает, и я получаю ошибку:

Ни один маршрут в таблице маршрутов не соответствует указанным значениям.

Так, BaseController метод не работает для меня.

Затем я попытался создать новый глобальный контроллер за пределами "Области", который должен вызывать любой вид. Это тоже не работает... Я не могу начать действие.

Вот как выглядит структура:

Как вы можете видеть, есть ряд областей, которые все должны иметь доступ к controller Я создал синим цветом Controllers папка.

Вот мой звонок с точки зрения:

 @Html.Action("GetLocalizedString", new { key = "Avatar" })

И вот мое действие:

[GET("getlocalizedstring")]
public ActionResult GetLocalizedString(string key)
{
    return Content(ResourceController.GetResourceManger(Identity)[key]);
}

Опять же, это работает на controller который сделал представление, но я не могу вызвать его с контроллера за пределами области или basecontroller, Я даже пытался добавить area = string.empty избавиться от собственности участка, но все равно не повезло.

РЕДАКТИРОВАТЬ 1 (Добавление конфигурации маршрута):

private void RegisterMVCRoutes()
{
    try
    {
        Application.Lock();

        RouteTable.Routes.Clear();

        System.Web.Http.GlobalConfiguration.Configure(c => { c.EnableCors(); c.MapHttpAttributeRoutes(); });

        RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        RouteTable.Routes.IgnoreRoute("{*allaxd}", new { allaxd = @".*\.axd(/.*)?" });

        // bring back MiniProfilers
        if (MiniProfiler.Settings.ProfilerProvider != null)
            StackExchange.Profiling.UI.MiniProfilerHandler.RegisterRoutes();

        RouteTable.Routes.MapAttributeRoutes(config =>
        {
            config.AddRoutesFromAssembly(System.Reflection.Assembly.GetExecutingAssembly());
            config.UseLowercaseRoutes = true;
        });

        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);

        int aspNetRoutingTableEntries = Components.PageRouteEngine.GetInstance().Initialize(RouteTable.Routes);

        // Page Routes for Design Mode
        if (Environment == Constants.SystemEnvironment.Staging || Environment == Constants.SystemEnvironment.RD)
        {
            RouteTable.Routes.Add(new CMSPageRoute("{*designUrlForAddColumn}", new { area = "CMS", controller = "Designer", action = "AddColumn" }, new { designUrlForAddColumn = @".*\.design/AddColumn(/.*)?" }, "CMS"));
            RouteTable.Routes.Add(new CMSPageRoute("{*designUrlForAddRowAbove}", new { area = "CMS", controller = "Designer", action = "AddRowAbove" }, new { designUrlForAddRowAbove = @".*\.design/AddRowAbove(/.*)?" }, "CMS"));
            RouteTable.Routes.Add(new CMSPageRoute("{*designUrlForAddRowAtBottom}", new { area = "CMS", controller = "Designer", action = "AddRowAtBottom" }, new { designUrlForAddRowAtBottom = @".*\.design/AddRowAtBottom(/.*)?" }, "CMS"));
            RouteTable.Routes.Add(new CMSPageRoute("{*designUrlForDeleteRow}", new { area = "CMS", controller = "Designer", action = "DeleteRow" }, new { designUrlForDeleteRow = @".*\.design/DeleteRow(/.*)?" }, "CMS"));
            RouteTable.Routes.Add(new CMSPageRoute("{*designUrlForUpdateUseFullWidthForRow}", new { area = "CMS", controller = "Designer", action = "UpdateUseFullWidthForRow" }, new { designUrlForUpdateUseFullWidthForRow = @".*\.design/UpdateUseFullWidthForRow(/.*)?" }, "CMS"));
            RouteTable.Routes.Add(new CMSPageRoute("{*designUrlForSaveMovedWidget}", new { area = "CMS", controller = "Designer", action = "SaveMovedWidget" }, new { designUrlForSaveMovedWidget = @".*\.design/SaveMovedWidget(/.*)?" }, "CMS"));
            RouteTable.Routes.Add(new CMSPageRoute("{*designUrlForAddNewWidget}", new { area = "CMS", controller = "Designer", action = "AddNewWidget" }, new { designUrlForAddNewWidget = @".*\.design/AddNewWidget(/.*)?" }, "CMS"));
            RouteTable.Routes.Add(new CMSPageRoute("{*designUrlForDeleteWidget}", new { area = "CMS", controller = "Designer", action = "DeleteWidget" }, new { designUrlForDeleteWidget = @".*\.design/DeleteWidget(/.*)?" }, "CMS"));
            RouteTable.Routes.Add(new CMSPageRoute("{*designUrlForMergeColumn}", new { area = "CMS", controller = "Designer", action = "MergeColumn" }, new { designUrlForMergeColumn = @".*\.design/MergeColumn(/.*)?" }, "CMS"));
            RouteTable.Routes.Add(new CMSPageRoute("{*designUrl}", new { area = "CMS", controller = "Designer", action = "Index" }, new { designUrl = @".*\.design(/.*)?" }, "CMS"));
        }

        // Page Routes... Page Index will also be a 404 catch all for routes not found.
        RouteTable.Routes.Add(new CMSPageRoute("{*url}", new { area = "CMS", controller = "Page", action = "Index" }, "CMS"));
    }
    finally
    {
        Application.UnLock();
    }
}

Я думаю, что большая часть конфигурации нашего маршрута зависит только от нас, но, возможно, это поможет. Еще раз спасибо.

1 ответ

Я закончил тем, что использовал подход, похожий на предложенный NightOwl888. Вместо вызова контроллера через @Html.Action() я написал метод расширения и вызвал его через @Html.Translate(). Это тянет "переводящий" код в единое центральное место и не требует от меня изменения каких-либо контроллеров. Поскольку мы сохраняем язык пользователя по умолчанию для веб-идентификатора пользователя, я должен был получить это из объекта HtmlHelper вместо того, чтобы полагаться на мой базовый контроллер. Вот код, который я в итоге использовал - надеюсь, он поможет кому-то еще.

    public static class ExtensionMethods
    {
        public static IHtmlString Translate(this HtmlHelper helper, string text)
        {
            if (string.IsNullOrWhiteSpace(text))
                return new HtmlString(string.Empty);

            var identity = (WebIdentity)helper.ViewContext.HttpContext.User.Identity;

            return new HtmlString(ResourceController.GetResourceManger(identity.Learner.SystemLanguageId)[text]);
        }
    }
Другие вопросы по тегам