4

我正在使用LocalizationAttributewhich implementsActionFilterAttribute来本地化视图。我只是装[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();
}

或者你有什么推荐的吗?

4

3 回答 3

7

我建议简单地扩展RazorViewEngine和覆盖FindPartialViewFindView以便通知 ViewEngine 查看线程内是否有当前文化的视图。如果找不到该页面,则照常进行。

  1. 延长RazorViewEngine
  2. 在 View 文件夹内应该有(假设英语是默认语言。)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...
}

应用程序启动

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new LocalizedRazorViewEngine());
于 2013-05-13T08:17:24.110 回答
2

我相信有很多方法可以实现这一点,但您可以按照下面的方法进行操作。

首先,您可以通过在视图名称中添加文化后缀来假设视图的一些命名约定,即 ViewName_ en-US .cshtml、ViewName_ pl-PL .cs​​html 等。

如果是这样,请不要根据当前文化在每个操作中分别构造这些名称。只需编写处理该问题的通用逻辑 - 具有覆盖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();
    }
}
于 2013-05-12T17:53:08.253 回答
1

您通常会在 Viewengine 中实现该规则。它比听起来容易。

http://biasecurities.com/2010/01/localized-asp-net-mvc-views-using-a-localizedviewengine/

于 2013-05-11T19:42:08.123 回答