原以為可以使用之前的多國語言方案進行程式設計了,沒想到第一個正式點的頁面就卡了,為什麼呢,因為通過HtmlHelper隻能找到目前請求的
View是哪個,如果這個View使用了Layout或是Partial就歇菜了。通過一番嘗試,發現使用
HtmlHelper.ViewDataContainer屬性可以獲得一個WebViewPage對象,這個對象中的VirtualPath對象代表當
前正在Excute的頁面屬于哪個實體檔案(.cshtml),于是修改代碼如下:
<code>public</code> <code>static</code> <code>class</code> <code>LocalizationHelper</code>
<code>{</code>
<code> </code><code>public</code> <code>static</code> <code>string</code> <code>Lang(</code><code>this</code> <code>HtmlHelper htmlhelper,</code><code>string</code> <code>key)</code>
<code> </code><code>{</code>
<code> </code><code>var viewPath = (htmlhelper.ViewDataContainer</code><code>as</code> <code>WebViewPage).VirtualPath;</code>
<code> </code><code>var viewName = viewPath.Substring(viewPath.LastIndexOf(</code><code>'/'</code><code>), viewPath.Length - viewPath.LastIndexOf(</code><code>'/'</code><code>)).TrimStart(</code><code>'/'</code><code>);</code>
<code> </code><code>var filePath = htmlhelper.ViewContext.HttpContext.Server.MapPath(viewPath.Substring(0, viewPath.LastIndexOf(</code><code>'/'</code><code>) + 1)) +</code><code>"App_LocalResources"</code><code>;</code>
<code> </code><code>var langs = htmlhelper.ViewContext.HttpContext.Request.UserLanguages.Union<</code><code>string</code><code>>(</code><code>new</code> <code>string</code><code>[] {</code><code>""</code> <code>});</code>
<code> </code><code>IEnumerable<DictionaryEntry> resxs =</code><code>null</code><code>;</code>
<code> </code><code>foreach</code> <code>(var lang</code><code>in</code> <code>langs)</code>
<code> </code><code>{</code>
<code> </code><code>var resxKey =</code>
<code> </code><code>string</code><code>.IsNullOrWhiteSpace(lang) ?</code><code>string</code><code>.Format(</code><code>@"{0}\{1}.resx"</code><code>, filePath, viewName) :</code><code>string</code><code>.Format(</code><code>@"{0}\{1}.{2}.resx"</code><code>, filePath, viewName, lang);</code>
<code> </code><code>resxs = GetResx(resxKey);</code>
<code> </code><code>if</code> <code>(resxs !=</code><code>null</code><code>) {</code><code>break</code><code>; }</code>
<code> </code><code>}</code>
<code> </code><code>return</code> <code>(</code><code>string</code><code>)resxs.FirstOrDefault<DictionaryEntry>(x => x.Key.ToString() == key).Value;</code>
<code> </code><code>}</code>
<code> </code><code>private</code> <code>static</code> <code>IEnumerable<DictionaryEntry> GetResx(</code><code>string</code> <code>resxKey)</code>
<code> </code><code>ObjectCache cache = MemoryCache.Default;</code>
<code> </code><code>if</code> <code>(cache.Contains(resxKey))</code>
<code> </code><code>resxs = cache.GetCacheItem(resxKey).Value</code><code>as</code> <code>IEnumerable<DictionaryEntry>;</code>
<code> </code><code>else</code>
<code> </code><code>if</code> <code>(File.Exists(resxKey))</code>
<code> </code><code>{</code>
<code> </code><code>resxs =</code><code>new</code> <code>ResXResourceReader(resxKey).Cast<DictionaryEntry>();</code>
<code> </code><code>cache.Add(resxKey, resxs,</code><code>new</code> <code>CacheItemPolicy() { Priority = CacheItemPriority.NotRemovable });</code>
<code> </code><code>}</code>
<code> </code><code>return</code> <code>resxs;</code>
<code>}</code>