ASP.NET MVC 3 Razor多言語リファレンスソリューション



3月22日整理:実用例参考:こちら
多言語をサポートするのは基本的に成熟した製品がサポートしなければならない機能ですが、この機能を使いたいと思ったとき、解決策が見つからなかったことに気づきました(驚いたですが、本当に提供していませんか?)、そこでネットで長い間検索して、2つの好きな案を発見しました.
1: ASP.NET MVCマルチ言語ソリューション
2: ASP.NET MVC - Localization Helpers
どちらもWebFormViewEngine向けで、Razorを使いたい私にとっては修正は必然です
2つ目はHttpContextを使っているようですGetLocalResourceObject()メソッド.しかし、問題はGetLocalResourceObject()メソッドを使用する場合、パラメータvirtualPathを提供する必要があります.このパラメータは長い時間をかけて成功しませんでした.肝心なのは、上の文のコードがいつも異常を投げていることです.
view source
print ? ResourceExpressionFields fields = (ResourceExpressionFields)builder.ParseExpression(expression, typeof ( string ), context);
いつもexpressionが間違っているとか、WebFormViewEngineでバインド式がRazorで使えない理由だと思いますが、WebForm式のバインド式をこっそりシミュレートして、依然として実行できません.また、公式にも完全な例は提供されていません.時間関係も研究したくありません.Razorで実験に成功した人がいたら、一言残してください.
もう1つ目は、個人的にはこれに慣れているような気がしますが、他のものは何でもいいです.どれも同じです.RexGenを使ってコンパイルしなければなりません.resxファイルは、それを.resourcesファイルを使用してから使用します.以前WebPageを使っていたときはそうではありませんでしたが、一歩多くても一歩も来ないので、MSDNを開けてみると、ResXResourceReaderというタイプが見つかりました.このタイプの名前から見ればいいものですが、コードを書くときにこのタイプが見つからないのですか?よく見ると、このタイプはSystemに定義されていた.Windows.Formsネーミングスペースの、WebプログラムにSystemを加える.Windows.Forms.dll引用はなんだか変な感じがしますが、考えてみればすべてです.NETの標準クラスライブラリは、合わせてもあまり影響はないはずですが、加えても使えるかどうかはまだ分かりません.
最初のソリューションを参照して、アシスタントクラスを作成します.
view source
print ?      public static class LocalizationHelpers      {          public static string Lang( this HtmlHelper htmlhelper, string key)          {              var viewPath = (htmlhelper.ViewContext.View as BuildManagerCompiledView).ViewPath;              var viewName = viewPath.Substring(viewPath.LastIndexOf( '/' ), viewPath.Length - viewPath.LastIndexOf( '/' )).TrimStart( '/' );              var filePath = htmlhelper.ViewContext.HttpContext.Server.MapPath(viewPath.Substring(0, viewPath.LastIndexOf( '/' ) + 1)) + "App_LocalResources" ;              var langs = htmlhelper.ViewContext.HttpContext.Request.UserLanguages;                  string resxPath = string .Format( @"{0}\{1}.resx" , filePath, viewName);                  foreach (var lang in langs)              {                  if (File.Exists( string .Format( @"{0}\{1}.{2}.resx" , filePath, viewName, lang)))                  {                      resxPath = string .Format( @"{0}\{1}.{2}.resx" , filePath, viewName, lang);                      break ;                  }              }                  string result = "" ;                  ResXResourceReader reader = new ResXResourceReader(resxPath);              var entry = reader.Cast<DictionaryEntry>().FirstOrDefault<DictionaryEntry>(x => x.Key.ToString() == key);                  if (entry.Value != null )              {                  result = ( string )entry.Value;              }                  return result;          }      }
 
この案は1つの参考原型としか言えないはずですが、まだ改善できるところがたくさんあります.例えば、方法にはCultureInfoなどのものが使われていません.当社の通常の案は言語がブラウザの言語設定に従っているので、簡単な点をテストするために、Requestの中のUserLanguagesに基づいてどの言語を表示するかを確定するだけです.また、毎回new 1つのReaderが性能に大きな影響を及ぼすかどうかはテストされていませんが、最も基本的な機能はあります.このスキームを使用すると、WebPageのようにリソースファイルを便利に使用することができます.
ところで、大切な内容を忘れそうになりましたが、この方法をどう使うか.
@Html.Lang("Test")
「Test」はリソースのKey
値の1つは、このLocalizationHelpersタイプのネーミングスペースがSystemである必要があることです.Web.Mvc
もし皆さんがもっと良い案があれば、私に知らせてください.ありがとうございます.
修正:サンプルソースコードのLocalizatioinHelpers 16行目のエラー、
var filePath = htmlhelper.ViewContext.HttpContext.Server.MapPath(viewPath.Substring(0, viewPath.Length - viewPath.LastIndexOf('/'))) + "App_LocalResources";
以下のように修正します.var filePath = htmlhelper.ViewContext.HttpContext.Server.MapPath(viewPath.Substring(0, viewPath.LastIndexOf( '/' ) + 1)) +  "App_LocalResources" ;
サンプルコード