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

      后记:第一次发布到主页,希望能够抛砖引玉,有玉的尽管砸,没玉的抛砖也不介意。