ASP.NET MVC 多語言方案

前言:

好多年沒寫文章了,工做很忙,每天加班, 天天都相信不用多久就會升職加薪當上總經理出任CEO迎娶白富美,走上人生巔峯,想一想還有點小激動~~~~html

直到後來發生了郵箱事件,我居然忘了給郵箱密碼賦值,致使遇到「郵箱不可用。 服務器響應爲: 5.7.1 Unable to relay for」的問題,網上一查後,讓Boss去設置IIS裏的SMTP。數據庫

結果Boss力證不用設置也能夠發,還給我發了N多Demo代碼,讓我蛋碎一地, 最後那點小激動,就在這小事件上栽沒了~~~json

好了,很少扯了,回正文吧~~~服務器


引子:

關於系統的多語言,我在以前的文章都寫過很多,包括秋色園QBlog的開源博客裏,也有相應的實現方案,不過隨着項目環境的不一樣,每每實現的方案也不盡相同。ide

今天就來扯扯,ASP.NET MVC下的方案。 this


1:數據的多語言:

在QBlog裏,數據的多語言,我是分紅兩種方案一塊兒處理:spa

A:多條數據,文章數據,用一個語言字段來標識該條數據爲什麼種語言。3d

B:對於其它數據,標題,公告等,用一個[#LangSplit]標識來分隔先後兩種語言。調試

不過如今的方案有點不一樣,看以下圖:code

 

看到大量的Xml字段了吧,這就是上一個項目繼承而來的精華,在項目裏動不了事實存在。

關於表名和字段命名方式,走的是國際範,大夥不要學。 

針對Xml,須要有一小套處理方案:

數據庫以Xml字段存檔多語言,格式爲:
< ML  V ="1.0" >
   < L ="zh-cn" >中文 </ M >
   < L ="en" >English </ M >
   < L =".." >其它語言 </ M >
</ ML >

而後針對這種存檔,須要有相應的處理:

SQL:查詢語法爲:

取值:字段名.value('(/ML/M[@L="zh-cn"])[1]','nvarchar(max)') 
取節點:字段名.query('/ML/M[@L="en"]') 
判斷:字段名.exists('/ML/M[@L="zh-cn"]') 
排序:用取值後的字段名進行排序


處理流程大致以下:

 

2:UI多語言

 2.1:MVC View的多語言流程:

 

通過對MVC的源碼調試,發如今Control基類(本身定義)統一處理便可。

Demo代碼:

         protected  override  void OnResultExecuted(ResultExecutedContext filterContext)
        {
             if (filterContext.Result  is ViewResult)
            {
                 string html = RenderViewToString( this, ((ViewResult)filterContext.Result).View);
                html = LanguageMgr.Replace(html, " zh ");
                Response.Clear();
                Response.Write(html);
            }
        }
         protected  static  string RenderViewToString(Controller controller, IView view)
        {
             // IView view = ViewEngines.Engines.FindView(controller.ControllerContext, viewName, masterName).View;
             using (System.IO.StringWriter writer =  new System.IO.StringWriter())
            {
                ViewContext viewContext =  new ViewContext(controller.ControllerContext, view, controller.ViewData, controller.TempData, writer);
                viewContext.View.Render(viewContext, writer);
                 return writer.ToString();
            }
        }

一開始的想法是處理完後寫回去,後來調試了半天源碼發現找不到寫回去的,靈光一閃,發現數據在Response.OutPut流裏,直接清空,輸出新的Html便可。

2.2:JS腳本的多語言流程:

 

具體的實現,看下面的語法定義。


3:UI多語言的語法方案

界面標籤訂義:[#對象名稱-字段名#],標籤內不容許帶有空格。


或者直接:[#字段名#](由Controller自動取得對象名稱處理)
例如:[#UserID#] 或者[#Login-UserID#]
中文時將被替換成:登錄名,英文就是Login了。

配套的Demo實現:

  public  class LanguageMgr
    {
         ///   <summary>
        
///  替換多語言。
        
///   </summary>
        
///   <param name="html"></param>
        
///   <param name="lang"></param>
        
///   <returns></returns>
         public  static  string Replace( string html,  string lang)
        {
            MatchCollection matchs = Regex.Matches(html,  @" \[#([\S\s]*?)#\] ", RegexOptions.Compiled | RegexOptions.IgnoreCase);
             if (matchs !=  null && matchs.Count >  0)
            {
                List< string> keys =  new List< string>(matchs.Count); // 記錄已匹配過的

                Dictionary< stringstring> dic = GetLanguageDic(lang);
                 foreach (Match match  in matchs)
                {
                     string text = match.Groups[ 0].Value;
                     string key = match.Groups[ 1].Value.Trim();
                     if (!keys.Contains(key))
                    {
                        keys.Add(key);
                         if (dic.ContainsKey(key))
                        {
                            html = html.Replace(text, dic[key]);
                        }
                    }
                }
                keys =  null;
                matchs =  null;
            }
             return html;
        }
         internal  static Dictionary< stringstring> GetLanguageDic( string lang)
        {
            Dictionary< stringstring> dic =  new Dictionary< stringstring>();
            dic.Add( " aaa "" 中文 ");
            dic.Add( " bbb "" 英文 ");
             return dic;
        }

  

4: JavaScript 多語言定義

對於JavaScript須要在客戶端調用的多語言,能夠在View中進行以下定義語言json:


< script >
var lang={loginID:」[#LoginID#]」,userName:」[#UserName#]」};
<script>
 

該View會在Controller端提早會替換成相應語言的文字。

以後的引用調用alert(lang.loginID)便可。

 

總結: 

以上的多語言方案,有特定的項目環境背景,僅供參考,討論,借鑑,檢討,請勿輕易模仿。

謝謝觀賞。

相關文章
相關標籤/搜索