zoukankan      html  css  js  c++  java
  • [原]ASP.NET MVC 3 Razor 多国语言参考解决方案 补充

    话说当年张古董将老婆借给了李成龙,结果最后竟然一借不回了。这件事呢两个方面都要怪:张古董动机不纯,李成龙作人也不厚道,但一般情况下占人便宜是很上瘾的。

    Reflector没有人不知道吧,.NET用了好多年的人可能已经不需要再去看.NET源代码了,一来是之前看过了,二来是很多的实现方式和运行原理能猜个七七八八的,但是对于初学者以及想查看有些不常用的.NET类型源代码的人来说,没有Reflector真是挺难受的。但是前两天突然听到个消息,Reflector居然收费了!!!这么好用的一个工具,居然不给免费使用了???这就好像张古董把老婆借给李成龙一样,让李成龙夜夜笙歌,好不逍遥快乐,有一天突然张古董要把老婆要回,李成龙寂寞冷清,肯定不是滋味,但好在张古董借出去的是个活物,也不知是啥原因居然就跟定李成龙了,让张古董来了个人财两空。但是Reflector是个死物,你就是再千呼万唤也得遵循主人的命令。又扯远了...

    进入正题:

    上文提到,使用System.Resources.ResXResourceReader(System.Windows.Forms.dll)类型获取资源文件中的项的方式实现了MVC下的Localization,但是这个方案只能算是个原型或是参考方案,今天又将这个类型研究了下,幸亏同事手头里有个没有升过级的Reflector,(我不小心点了不自动升级按钮,这应该不算是侵权吧),打开看了ResXResourceReader的实现原理,原来该类型就是使用解析XML的方式把资源项给拿了出来,放到了一个IDictionaryEnumerator里面。

    这样就清楚多了,该类型可以在Web程序里面安全的使用;这个类型主要的开销在于读取以及解析resx文件上面。平时习惯上我比较喜欢使用缓存来解决某些情景下的性能问题,这次没有例外,.NET4中出一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;
            }
        }
    

  • 相关阅读:
    分享自制的C#和VB Code互转工具
    C# winform 学习(一)
    C# winform 学习(二)
    C# winform 学习(二)
    C# Winform 学习(四)
    C# Winform 学习(四)
    C# winform 学习(三)
    C# winform 学习(三)
    C# Winform学习(六)
    C# Winform学习(六)
  • 原文地址:https://www.cnblogs.com/think8848/p/1987072.html
Copyright © 2011-2022 走看看