2013-05-11 28 views
4

我使用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(); 
} 

或者你推薦別的東西嗎?

回答

6

我會建議簡單地擴展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()); 
2

我相信,有許多方法來實現這一點,但你可以遵循下面這一個。

首先,你可以假設一些命名約定的意見,加入文化後綴以他們的名字即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(); 
    } 
}