根据当前文化调用不同(本地化)视图
本文关键字:本地化 视图 调用 文化 | 更新日期: 2023-09-27 18:13:12
我使用LocalizationAttribute
实现ActionFilterAttribute
来本地化视图。我只是把[Localize]
放在控制器上。我用的是LocalizeStrings。基于当前线程上使用的语言来应用Resx文件。一切都适用于这个简单的情况(使用本地化字符串)。现在我想本地化完整的页面(而不仅仅是字符串)。
要实现这一点,您使用哪种方法?
我需要识别哪个线程是当前控制器上,并基于该值调用视图:
public ActionResult AboutUs()
{
switch (Thread.CurrentThread.CurrentUICulture.Name)
{
case "en-US":
return View("EnglishUSView");
case "de-DE":
return View("GermanView");
default:
return View();
}
return View();
}
我建议简单地扩展RazorViewEngine
并覆盖FindPartialView
和FindView
,以便通知ViewEngine查看线程内是否有当前文化的视图。如果找不到该页,就像往常一样继续。
- 扩展
RazorViewEngine
- 在视图文件夹中应该有(假设英语是默认语言)。
Index.cshtml
和Index.de-DE.cshtml
- 修改
Global.asax.cs
文件,在应用程序开始时,你应该调用本地化的视图引擎(实现RazorViewEngine的那个)
no further modification needed
/Views/Home/Index.cshtml
/Views/Home/Index.de.DE.cshtml
辅助public class LocalizedRazorViewEngine : RazorViewEngine
{
public override ViewEngineResult FindPartialView ...
public override ViewEngineResult FindView...
}
ApplicationStart
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new LocalizedRazorViewEngine());
我相信有很多方法可以做到这一点,但你可以遵循下面的方法。
首先,您可以假设视图的一些命名约定,通过在其名称中添加文化后缀,即ViewName_en-US。cshtml, ViewName_ pl-PL 。cshtml等。
如果是,请不要根据当前区域性分别在每个操作中构造这些名称。只需编写通用逻辑,使用覆盖的OnActionExecuted
方法来处理基础控制器:
public class BaseController : Controller
{
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
var view = filterContext.Result as ViewResultBase;
if(view != null)
{
var viewName = string.IsNullOrEmpty(view.ViewName)
? filterContext.RouteData.Values["action"].ToString()
: view.ViewName; // retrieve the custom view name if provided or default action name otherwise
var cultureName = Thread.CurrentThread.CurrentUICulture.Name;
var localizedViewName = string.Format("{0}_{1}", viewName, cultureName); // construct composite, culture-aware name
if (ViewExists(localizedViewName)) // safety check in case not all your views are localized - if so, just return the default name
{
filterContext.Result = new ViewResult { ViewName = localizedViewName };
}
}
}
private bool ViewExists(string name)
{
var result = ViewEngines.Engines.FindView(ControllerContext, name, null);
return result.View != null;
}
}
操作现在不需要任何本地化处理:
public class HomeController : BaseController
{
public ActionResult AboutUs()
{
// (...) nothing special here
return View();
}
}
您通常会在Viewengine中实现该规则。它比听起来容易。
http://biasecurities.com/2010/01/localized-asp-net-mvc-views-using-a-localizedviewengine/