[原]ASP.NET MVC 3 Razor多言語リファレンスソリューション補足
5721 ワード
ところで、張骨董品は妻を李成龍に貸したが、結局借りられなかった.このことはどちらもおかしい:張骨董品の動機は純粋ではなく、李成龍は人を作るのも厚かましくないが、一般的には人を安くするのは中毒だ.
Reflector知らない人はいないでしょう.NETは何年も使っている人はもう見に行く必要はないかもしれません.NETソースコードは、一つは前に見たことがありますが、二つ目は多くの実現方法と運行原理が推測できますが、初心者や見たい人にはよくありません.NETタイプのソースコードの人にとって、Reflectorがないのはつらいです.しかし先日突然ニュースを闻いて、Reflectorは意外にも有料になりました!!!こんな使いやすいツールを、無料で使わないなんて???これはまるで張骨董品が妻を李成龍に貸したように、李成龍に夜夜笙歌を歌わせた.しかしReflectorは死んだもので、あなたはどんなに呼んでも主人の命令に従わなければなりません.また遠ざかった...
本題に入る:
前文において、Systemが使用する.Resources.ResXResourceReader(System.Windows.Forms.dll)タイプはリソースファイルのアイテムを取得する方法でMVC下のLocalizationを実現しましたが、このシナリオはプロトタイプか参考シナリオとしか言えません.今日またこのタイプを検討しましたが、同僚の手元に昇格していないReflectorがいてよかったのです(自動アップグレードボタンをうっかり注文しましたが、これは権利侵害ではないでしょう).ResXResourceReaderの実現原理を見てみると、このタイプは解析XMLを使ってリソース項目を取り出し、IDictionaryEnumeratorの中に入れたものだった.
このようにして、このタイプはWebプログラムの中で安全に使用することができます.このタイプの主なオーバーヘッドはresxファイルの読み取りと解析にあります.普段はキャッシュを使ってパフォーマンスの問題を解決するのが好きですが、今回は例外ではありません.NET 4からSystemが出る.Runtime.Caching.MemoryCacheはまだ使ったことがないので、手の練習に出しました.
piapiaの場合、上記のコードを以下のように変更します.
OK、基本的にこの案はプロジェクトに使えると思います.
3月19日に内容を更新し、Langメソッドを書き換え、リソースファイルが存在するかどうかを検証する手順を減らした-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Reflector知らない人はいないでしょう.NETは何年も使っている人はもう見に行く必要はないかもしれません.NETソースコードは、一つは前に見たことがありますが、二つ目は多くの実現方法と運行原理が推測できますが、初心者や見たい人にはよくありません.NETタイプのソースコードの人にとって、Reflectorがないのはつらいです.しかし先日突然ニュースを闻いて、Reflectorは意外にも有料になりました!!!こんな使いやすいツールを、無料で使わないなんて???これはまるで張骨董品が妻を李成龍に貸したように、李成龍に夜夜笙歌を歌わせた.しかしReflectorは死んだもので、あなたはどんなに呼んでも主人の命令に従わなければなりません.また遠ざかった...
本題に入る:
前文において、Systemが使用する.Resources.ResXResourceReader(System.Windows.Forms.dll)タイプはリソースファイルのアイテムを取得する方法でMVC下のLocalizationを実現しましたが、このシナリオはプロトタイプか参考シナリオとしか言えません.今日またこのタイプを検討しましたが、同僚の手元に昇格していないReflectorがいてよかったのです(自動アップグレードボタンをうっかり注文しましたが、これは権利侵害ではないでしょう).ResXResourceReaderの実現原理を見てみると、このタイプは解析XMLを使ってリソース項目を取り出し、IDictionaryEnumeratorの中に入れたものだった.
このようにして、このタイプはWebプログラムの中で安全に使用することができます.このタイプの主なオーバーヘッドはresxファイルの読み取りと解析にあります.普段はキャッシュを使ってパフォーマンスの問題を解決するのが好きですが、今回は例外ではありません.NET 4からSystemが出る.Runtime.Caching.MemoryCacheはまだ使ったことがないので、手の練習に出しました.
piapiaの場合、上記のコードを以下のように変更します.
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;
}
}
var result = ResXCache.GetResValue(resxPath, key);
return result;
}
public static class ResXCache
{
public static string GetResValue(string file, string key)
{
ObjectCache cache = MemoryCache.Default;
IEnumerable<DictionaryEntry> resxs = null;
if (cache.Contains(file) == false)
{
resxs = new ResXResourceReader(file).Cast<DictionaryEntry>();
cache.Add(file, resxs, new CacheItemPolicy() { Priority = CacheItemPriority.NotRemovable });
}
else
{
resxs = cache.GetCacheItem(file).Value as IEnumerable<DictionaryEntry>;
}
return (string)resxs.FirstOrDefault<DictionaryEntry>(x => x.Key.ToString() == key).Value;
}
}
}
OK、基本的にこの案はプロジェクトに使えると思います.
3月19日に内容を更新し、Langメソッドを書き換え、リソースファイルが存在するかどうかを検証する手順を減らした-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
public static class LocalizationHelper
{
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.Union<string>(new string[] { "" });
IEnumerable<DictionaryEntry> resxs = null;
foreach (var lang in langs)
{
var resxKey =
string.IsNullOrWhiteSpace(lang) ? string.Format(@"{0}\{1}.resx", filePath, viewName) : string.Format(@"{0}\{1}.{2}.resx", filePath, viewName, lang);
resxs = GetResx(resxKey);
if (resxs != null) { break; }
}
return (string)resxs.FirstOrDefault<DictionaryEntry>(x => x.Key.ToString() == key).Value;
}
private static IEnumerable<DictionaryEntry> GetResx(string resxKey)
{
ObjectCache cache = MemoryCache.Default;
IEnumerable<DictionaryEntry> resxs = null;
if (cache.Contains(resxKey))
{
resxs = cache.GetCacheItem(resxKey).Value as IEnumerable<DictionaryEntry>;
}
else
{
if (File.Exists(resxKey))
{
resxs = new ResXResourceReader(resxKey).Cast<DictionaryEntry>();
cache.Add(resxKey, resxs, new CacheItemPolicy() { Priority = CacheItemPriority.NotRemovable });
}
}
return resxs;
}
}