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

それとも何か他のものをお勧めしますか?

4

3 に答える 3

7

単純に拡張RazorViewEngineしてオーバーライドすることをお勧めします。ViewEngine に通知するために、スレッド内に現在のカルチャがあるビューがありますFindPartialViewFindViewそのページが見つからない場合は、通常どおり続行してください。

  1. 拡張するRazorViewEngine
  2. View フォルダー内には、(英語がデフォルトの言語であると仮定して)Index.cshtmlIndex.de-DE.cshtml
  3. ファイルを変更します。アプリケーションの開始内で、ローカライズされたビュー エンジン ( RazorViewEngineGlobal.asax.csを実装するもの) を呼び出す必要があります。

コントローラ

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 に答える