支持中英文多語言瀏覽的MVC網站實例


思路大概是這樣的,將翻譯成不同語言的詞句以xml鍵值對的格式分別存在不同文件夾下,擴展MVC HtmlHelper, 在擴展方法里根據用戶當前訪問Action所在的路徑以及當前所選的語言類型讀取語言文件夾下的xml文件,再通過HtmlHelper傳過來的key獲取對應的value。若找不到,則將key自動添加到相應的文件里面。切換語言時將所選的語言類型保存在Session,再Redirect。

寫一個靜態類LangHelper,用以操作語言文件。本例中,將中文、英文語言文件分別保存在網站根目錄下Resources下的zh-cn和en文件夾里面,文件類型為res。為防止每次訪問都去讀取操作那些語言文件,我聲明一個Dictionary靜態變量,用來保存訪問過的語言文件里的key\value,在下次(別的用戶)訪問時先從已保存在服務器內存的靜態字典中讀取。這樣就加快了訪問速度。

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Web;

namespace Utility
{
    public static class LangHelper
    {
        //全局靜態變量
        private static Dictionary<string, LanguageInfo> Languages = new Dictionary<string, LanguageInfo>();

        public static string GetLangString(string key, string langType)
        {
            if (String.IsNullOrEmpty(key))
                throw new ArgumentException("key can not be null!", "key");
            if (String.IsNullOrEmpty(langType))
                throw new ArgumentException("language type can not be null!", langType);


            string filename = "common";
            langType = langType.ToLower();
            LanguageInfo info = GetLanguageInfo(langType, filename);//默認先到通用的語言文件里去找
            if (info.LanguageDictionary.ContainsKey(key.ToLower()))
                return info.LanguageDictionary[key.ToLower()];
            else
            {
                string filePath = HttpContext.Current.Request.FilePath;
                if (filePath == HttpContext.Current.Request.ApplicationPath)
                {
                    info.AddKey(key, key);//添加到通用語言文件
                    return key;
                }
                else
                {
                    if (filePath[0] == '/') filePath = filePath.Substring(1, filePath.Length - 1);
                    string[] words = filePath.Split(new char[] { '/' });
                    filename = String.Format("{0}", words[0]);//當前Controller所在的文件夾名字,也即語言文件的名字
                    info = GetLanguageInfo(langType, filename);
                    if (info.LanguageDictionary.ContainsKey(key.ToLower()))
                        return info.LanguageDictionary[key.ToLower()];
                    else
                    {
                        info.AddKey(key, key);
                        return key;
                    }
                }
                
            }
        }

        private static LanguageInfo GetLanguageInfo(string langType, string filename)
        {

            string cacheKey = String.Format("{0}{1}", langType, filename);
            LanguageInfo info = null;
            if (Languages.ContainsKey(cacheKey))
                info = Languages[cacheKey];
            else
            {
                info = new LanguageInfo(langType, filename);
                if (filename != "common") Languages.Clear();
                Languages[cacheKey] = info;
            }
            return info;
        }
    }

    public class LanguageInfo
    {

        public string LanguageCode { get; set; }

        public string ResourceFile { get; set; }

        public XElement RootElement { get; private set; }

        public Dictionary<string, string> LanguageDictionary { get; private set; }

        public LanguageInfo(string languageCode, string resourceFile)
        {
            this.LanguageCode = languageCode;
            this.ResourceFile = HttpContext.Current.Server.MapPath(
                String.Format("~/Resources/{0}/{1}.res",languageCode, resourceFile));
            this.LanguageDictionary = this.BuildLanguageDictionary();
        }

        /// <summary>
        /// 讀取XML文件構建語言字典
        /// </summary>
        /// <returns></returns>
        public Dictionary<string, string> BuildLanguageDictionary()
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();
            if (System.IO.File.Exists(ResourceFile))
                RootElement = XElement.Load(ResourceFile);
            else
            {
                RootElement = new XElement("language");
            }
            IEnumerable<XElement> adds = RootElement.Elements();
            foreach (XElement add in adds)
            {
                string k = add.Attribute("key").Value;
                string v = add.Attribute("value").Value;
                dic[k.ToLower()] = v;
            }
            return dic;
        }

        public void SaveKey(string key, string value)
        {
            if (String.IsNullOrEmpty(key) || string.IsNullOrEmpty(value)) return;
            XElement e = RootElement.Elements().Where(a => a.Attribute("key").Value.ToLower() == key.ToLower()).FirstOrDefault();
            if (e == null) return;
            e.SetAttributeValue("value", value);
            RootElement.Save(ResourceFile);
        }
        /// <summary>
        /// 向語言文件添加鍵值對
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void AddKey(string key, string value)
        {
            XElement newel = new XElement("add");
            newel.SetAttributeValue("key", key);
            newel.SetAttributeValue("value", key);
            RootElement.Add(newel);
            try
            {
                RootElement.Save(ResourceFile);
            }
            catch (Exception e)
            {
            }
            LanguageDictionary[key.ToLower()] = value;
        }

        public void RemoveKey(string key)
        {
            if (String.IsNullOrEmpty(key)) return;
            XElement e = RootElement.Elements().Where(a => a.Attribute("key").Value.ToLower() == key.ToLower()).FirstOrDefault();
            if (e == null) return;
            e.Remove();
            RootElement.Save(ResourceFile);
        }
    }
}

GlobalizeUtil 類用來控制當前用戶選擇的語言類型

View Code
public class GlobalizeUtil
    { 
        public static string GetCurrentLanguage()
        {            
            object lang = HttpContext.Current.Session["language"];
            if (lang == null)
                return "zh-cn";
            else
                return lang.ToString();            
        }

        public static void SetCurrentLanguage(string langCode)
        {
            HttpContext.Current.Session["language"] = langCode;
        }
    }

擴展MVC HtmlHelper,方便在View中調用。擴展方法名為String,需要一個string類型參數,此參數即為key,當語言文件中不存在此key時,將此key直接作為value輸出,並保存在語言文件中。

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Web;
using System.Web.Mvc;
using System.Xml.Linq;
namespace Utility
{
    public static class Extensions
    {
        /// <summary>
        /// 在Mvc View中調用
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string String(this HtmlHelper htmlHelper, string key)
        {
            return htmlHelper.Encode(GetLangString(key));
        }

        /// <summary>
        /// 在C#代碼中使用
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string LangString(string key)
        {
            return GetLangString(key);
        }

        private static string GetLangString(string key)
        {            
            string langType = GlobalizeUtil.GetCurrentLanguage();
            return LangHelper.GetLangString(key, langType);
        } 
      
    } 

 
}

在View中的使用如: Html.String("Username"),在common.res語言文件里面就會添加一條 <add key="Username" value="Username" />記錄,將zh-cn文件夾下的common.res里這條記錄的value改為"用戶名",則當用戶在中英文之間切換時就會按不同語言顯示。

效果圖一:

效果圖二:

不知有沒有更好的方法,歡迎指教!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM