說說傳統做法的缺點
1、做過多語言的都知道這玩意兒太花時間
2、多語言架構一般使用資源文件、XML或者存儲數據庫來實現。這樣就在一定程序上降低了性能
3、頁面的可讀性變差,需要和資源文件進行來回切換
4、修改麻煩
5、樣式兼容難調
6、JS如何處理
另類做法
傳統做法看上去高大上實質上維護起來確實很費力,所以有一部分人就采用了另類做法直接做二套頁面。總體來說上面一種和下面一種可以說半斤八兩。
上面一種顯的有點檔次,但維護成本並不低,頁面可讀性差,樣式兼容難調,唯一優點是頁面代碼邏輯只有一套,只在這一點上占了優勢。
另類做法升級版
為了快速開發和易維護性我對另類方法進行了2點升級
1、重寫MVC默認視圖引擎
在Gobal Application_Start中添加自定義視圖引擎,只看紅圈內容
return view時會根據Cookie里面的語言后綴找到相應的cshtml文件,BestViewEngine具體內容如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using Best.WidgetFactory.Cache; using SyntacticSugar; namespace Best.Site.Models { /// <summary> /// 自定義MVC視圖引擎 /// </summary> public sealed class BestViewEngine : RazorViewEngine { public BestViewEngine() { } /// <summary> /// 重寫FindView /// </summary> /// <param name="controllerContext"></param> /// <param name="viewName"></param> /// <param name="masterName"></param> /// <param name="useCache"></param> /// <returns></returns> public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) { var key ="languageKey";//COOKIE KEY var cm = CookiesManager<string>.GetInstance(); if (cm.ContainsKey(key))//驗證多語言COOKIE是否有值 { var cacheVal = cm[key]; //獲取多語言后綴 (例如: en) if (cacheVal.IsValuable()) viewName += "_{0}".ToFormat(cm[key]);//將原視圖名添加后綴 比如 index 添加后綴之后就是 index_en } return base.FindView(controllerContext, viewName, masterName, useCache);//參數處理后調用BASE的FindView方法 } } }
2、添加擴展函數讓一個js支持多種語言的cshtml (例如:index.js 可以用在 index.cshtml和index_en.cshtml)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web.Mvc; using SyntacticSugar; using System.Text.RegularExpressions; public static class HtmlHelperExtensions { public static MvcHtmlString PageLanguage(this HtmlHelper helper, object obj) { string str=obj.ModelToJson();//將對象轉為json StringBuilder sb = new StringBuilder(); sb.Append("<script> var $pageLanguage = "); sb.Append(str); sb.Append("</script>"); MvcHtmlString mvcString = new MvcHtmlString(sb.ToString()); return mvcString; } }
cshtml中如何使用這個擴展函數(如下圖)
JS里面調用PageLanguage屬性
目錄結構如下,當用戶訪問 /Role/index ,我們COOKIE里面存的是 en 那么 return view 本來找到的是 index.cshtml 經過我們的重寫就會找到
index_en.cshtml
如果要添加更多語言我們只要添加相應的cshtml和cookie,JS和后台代碼全部一致
回顧一下代碼:
index_en.cshtml
index.cshtml
統一的JS(只看紅圈部分便可)
是不是比資源文件好維護呢?性能也是最高不是嗎?