根据当前文化调用不同(本地化)视图

本文关键字:本地化 视图 调用 文化 | 更新日期: 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并覆盖FindPartialViewFindView,以便通知ViewEngine查看线程内是否有当前文化的视图。如果找不到该页,就像往常一样继续。

  1. 扩展RazorViewEngine
  2. 在视图文件夹中应该有(假设英语是默认语言)。Index.cshtmlIndex.de-DE.cshtml
  3. 修改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/