ASP.NET MVC 3 Razor 多国语言参考解决方案 补充

简介: 转自 http://www.cnblogs.com/think8848/archive/2011/03/17/1987072.html 话说当年张古董将老婆借给了李成龙,结果最后竟然一借不回了。

转自 http://www.cnblogs.com/think8848/archive/2011/03/17/1987072.html

 

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


 

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;
    }
}

 

目录
相关文章
|
7月前
|
API C++ Windows
Visual C++运行库、.NET Framework和DirectX运行库的作用及常见问题解决方案,涵盖MSVCP140.dll丢失、0xc000007b错误等典型故障的修复方法
本文介绍Visual C++运行库、.NET Framework和DirectX运行库的作用及常见问题解决方案,涵盖MSVCP140.dll丢失、0xc000007b错误等典型故障的修复方法,提供官方下载链接与系统修复工具使用指南。
1693 2
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
987 3
|
监控 Linux
yum install -y net-snmp-devel 安装不成功 zabbix项目安装,Errors during downloading metadata for repository ‘extras-common’:问题解决方案-优雅草卓伊凡
yum install -y net-snmp-devel 安装不成功 zabbix项目安装,Errors during downloading metadata for repository ‘extras-common’:问题解决方案-优雅草卓伊凡
723 13
yum install -y net-snmp-devel 安装不成功 zabbix项目安装,Errors during downloading metadata for repository ‘extras-common’:问题解决方案-优雅草卓伊凡
|
开发框架 .NET PHP
ASP.NET Web Pages - 添加 Razor 代码
ASP.NET Web Pages 使用 Razor 标记添加服务器端代码,支持 C# 和 Visual Basic。Razor 语法简洁易学,类似于 ASP 和 PHP。例如,在网页中加入 `@DateTime.Now` 可以实时显示当前时间。
|
监控 网络安全 调度
Quartz.Net整合NetCore3.1,部署到IIS服务器上后台定时Job不被调度的解决方案
解决Quartz.NET在.NET Core 3.1应用中部署到IIS服务器上不被调度的问题,通常需要综合考虑应用配置、IIS设置、日志分析等多个方面。采用上述策略,结合细致的测试和监控,可以有效地提高定时任务的稳定性和可靠性。在实施任何更改后,务必进行充分的测试,以验证问题是否得到解决,并监控生产环境的表现,确保长期稳定性。
1592 1
|
存储 安全 物联网
.NET 跨平台工业物联网网关解决方案
【9月更文挑战第28天】本文介绍了利用 .NET 构建跨平台工业物联网网关的解决方案。通过 .NET Core 和多种通信协议(如 MQTT 和 Modbus),实现工业设备的高效接入和数据采集。系统架构包括设备接入层、数据处理层、通信层、应用层和数据库层,确保数据的准确采集、实时处理和安全传输。此外,还详细阐述了设备身份认证、数据加密及安全审计等机制,确保系统的安全性。该方案适用于不同操作系统和工业环境,具备高度灵活性和扩展性。
504 2
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
409 7
|
API C#
.NET电子邮件高效处理解决方案
.NET电子邮件高效处理解决方案
216 2
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
355 0
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
339 0