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:
/// </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
后记:第一次发布到主页,希望能够抛砖引玉,有玉的尽管砸,没玉的抛砖也不介意。