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"
;
サンプルコード