Cool MVC: 多语言的另一种解决方案
Hello,这篇文章之所以叫 MVC多语言的另一种解决方案, 是因为园子里已经有一篇叫《ASP.NET MVC 多语言解决方案》的文章了。文中提到:这里使用了 .resx 资源文件,注意这里这个文件需要被编译后才能使用,否则找不到已经增加的项。编译这个可以使用.NET 自带的 ResGen.exe。 意思就是每次更新.resx资源文件后,都要用ResGen来重新生成.resources的文件才可以使用。嗯,转成.resources的文件除了减少一点存储空间,还有什么优势呢?这个没测试过,真要问Microsoft才知道。 现在本文提出的这种多语言方案不需要额外生成.resources文件,只要.resx就可以了。.resx文件其实一言以蔽之是name-value集的xml文件,因此,自然而然产生直接使用.resx的多语言方案:
1.通过读取xml的方法来加载所有的name-value到内存,以后就可以像查字典这样查询相应的语言值。
2.使用FileSystemWatcher来监视语言文件,如果有更新就自动更新相应的语言。
至于使用也是很简单,跟前一种方案一样:<%=Html.Lang("key") %> ,如果在Controller中使用,直接:this.Lang(“key”);
为了便于扩展(可能你的语言文件不是.resx,而是直接从数据库读取的),方案中定义了语言提供接口:
/// <summary> /// 语言提供者接口 /// </summary> public interface ILanguageProvider { /// <summary> /// 查询相应语言值 /// </summary> /// <param name="lang">语言名称</param> /// <param name="key">键</param> /// <returns></returns> string GetLanguage(string lang, string key); }
至于实现,前面已大体介绍了原理,这里不贴代码,可以到文章最后那里下载完整的代码。
跟很多mvc例子一样,也是通过扩展HtmlHelper和Controller来实现,似乎除了扩展它,我也想不到更好的了。
/// <summary> /// Author:Bruce /// Blog: http://coolcode.cnblogs.com /// </summary> public static class LocalizationHelpers { /// <summary> /// 在 Html 中直接使用 /// </summary> /// <param name="htmlhelper"></param> /// <param name="key"></param> /// <returns></returns> public static string Lang(this HtmlHelper htmlhelper, string key) { return GetLangString( key); } public static string Lang(this Controller control, string key) { return GetLangString(key); } private static ILanguageProvider langProvider = null; private static string GetLangString(string key) { HttpRequest Request = HttpContext.Current.Request; /*默认语言是英文*/ string lang = "en-us"; /*检查cookies是否有用户的语言设置*/ if (Request.Cookies["CoolCode_Lang"] != null) lang = Request.Cookies["CoolCode_Lang"].Value; /*如果cookies中没有就取客户端的语言*/ else if (Request.UserLanguages.Length > 0) { lang = Request.UserLanguages[0]; } /*加载语言,只在第一次使用时加载*/ if (langProvider == null) { langProvider = new LanguageProvider(); } return langProvider.GetLanguage(lang, key); } }
另外附上从资源文件读取语言的方法:
/// <summary> /// 加载语言文件(这里语言文件是一般资源文件,其实只要是符合这样结构的xml文件就可以: /// <data name="key"><value>文本</value></data>) /// </summary> /// <param name="fileName">语言文件路径</param> public void Read(string fileName) { var xe = XElement.Load(fileName); var xes = xe.Elements().Where(c => c.Name == "data" && c.Attribute("name") != null && c.Element("value") != null).ToList(); foreach (var x in xes) { this.Add(x.Attribute("name").Value, x.Element("value").Value); } }
是不是很简单?
完整代码:CoolCode.MultiLanguage.zip
后记:第一次发布到主页,希望能够抛砖引玉,有玉的尽管砸,没玉的抛砖也不介意。