我正致力于将全球化 / 本地化添加到相当大规模的应用程序中。除了观点本身,一切都很完整。到目前为止,我的方法是添加一个全局操作,每个视图都可以调用它来获取本地化字符串。我遇到的问题是我似乎无法创造出这样的全球行动。
到目前为止,我向常规action
添加了controller
...我可以点击它,一切正常。但是,当我将此方法移动到BaseController中时,操作不再被命中,我收到错误:
路由表中没有路由与提供的值匹配。
所以,BaseController
方法并不适合我。
接下来,我尝试在" Areas"之外创建一个新的全局控制器。任何视图都应该能够调用。这也不起作用......我无法采取行动。
这是结构的样子:
正如您所看到的,有许多区域都必须有权访问我在蓝色突出显示的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();
}
}
我认为我们的大部分路线配置仅针对我们应用,但也许会有所帮助。再次感谢。
答案 0 :(得分: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]);
}
}