2017-02-17 112 views
1

我正在努力將全球化/本地化到一個相當大規模的應用程序。除了意見本身之外,一切都是完整的。到目前爲止,我的方法是添加一個全局操作,每個視圖都可以調用以獲取本地化的字符串。我遇到的問題是我似乎無法創建這樣的全球行動。如何實施MVC全球行動

到目前爲止,我添加了一個action到我的正常controller ...我可以打它,一切正常。然而,當我提出這個方法到BaseController動作不再被擊中,我得到的錯誤:

No route in the route table matches the supplied values.

所以,BaseController方法不是爲我工作。

接下來,我試圖在任何視圖應該能夠調用的「區域」之外創建一個新的全局控制器。這也行不通...我無法實現這一行動。

這裏的結構是什麼樣子:

enter image description here

正如你可以看到有一些領域所有必須能夠訪問我的藍色創建的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來擺脫區域屬性,但仍然沒有運氣。

EDIT 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(); 
    } 
} 

我想大多數路由的配置是針對應用的只有我們的,但也許會有所幫助。再次感謝。

+0

你的路由配置是什麼樣的? – jao

+0

附註:爲什麼常規自動生成的資源字符串訪問類不適合你? –

+0

@jao - 我們的路由配置非常大,但沒有什麼特別的。我會暫時更新和發佈。 – BrianLegg

回答

0

我最終使用了一種類似於NightOwl888建議的方法。我沒有通過@ Html.Action()調用控制器,而是寫了一個擴展方法,並通過@ Html.Translate()調用它。這將「翻譯」代碼拉到一箇中心位置,不需要我修改任何控制器。因爲我們將用戶語言默認存儲在用戶的Web身份上,所以我必須從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]); 
     } 
    }