原以为可以使用之前的多国语言方案进行编程了,没想到第一个正式点的页面就卡了,为什么呢,因为通过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>