ASP.NET MVC 3 Razor 多國語言參考解決方案

來源:互聯網
上載者:User

轉自 http://www.cnblogs.com/think8848/archive/2011/03/15/1984793.html

 

3月22日整理:實用樣本請參考:這裡

支援多國語言基本上是一個成熟產品必須支援的功能,但是直到想用這個功能時,發現居然找不到解決方案(很吃驚,真的沒有提供嗎?),於是在網上搜尋了好久,發現兩種心儀的方案:

1: ASP.NET MVC 多語言解決方案

2: ASP.NET MVC - Localization Helpers

這兩種方案都是針對WebFormViewEngine的,對於想使用Razor的我來說,修改是必然的了

先說說第二種,這個方法貌似核心是使用了HttpContext.GetLocalResourceObject()方法。但是問題在於在使用
GetLocalResourceObject()方法時,需要提供一個參數virtualPath,這個參數花了好久心思沒有成功,關鍵是上面有句代碼
老是會拋異常:

ResourceExpressionFields fields = (ResourceExpressionFields)builder.ParseExpression(expression, typeof(string), context);

總是說expression不對之類的,我猜應該是在WebFormViewEngine裡面綁定運算式不能在Razor裡使用的原因吧,但是我偷
偷的類比了一個WebForm式的綁定運算式,依然不能執行通過。而且官方也沒有提供一個完整的樣本,時間關係我也不想研究了,如果有人在Razor上試
驗成功了,麻煩留個言。

再來說第一種,個人感覺習慣上這個除了一樣,其它的啥都好,哪一樣呢,就是必須使用RexGen來編譯.resx檔案,使其成
為.resources檔案,然後再去使用。在以前使用WebPage時是沒有這一步的,多一步總沒有少一步來的方便,因此又開啟MSDN來看看,一看發
現一個類型:ResXResourceReader,從這個類型的名稱上看就是一個好東西,但是在寫代碼時居然發現找不到該類型?再仔細一看,原來這個類
型居然是定義在System.Windows.Forms命名空間中的,在Web程式中加入System.Windows.Forms.dll引用總感覺
是怪怪的,但是想想都是.NET的標準類庫,加起來應該也沒有太大的影響,再說還不知道加進來能不能用。

於是參照第一種解決方案做出一個助手類:

    public static class LocalizationHelpers
    {
        public static string Lang(this HtmlHelper htmlhelper, string key)
        {
            var viewPath = (htmlhelper.ViewContext.View as BuildManagerCompiledView).ViewPath;
            var viewName = viewPath.Substring(viewPath.LastIndexOf('/'), viewPath.Length - viewPath.LastIndexOf('/')).TrimStart('/');
            var filePath = htmlhelper.ViewContext.HttpContext.Server.MapPath(viewPath.Substring(0, viewPath.LastIndexOf('/') + 1)) + "App_LocalResources";
            var langs = htmlhelper.ViewContext.HttpContext.Request.UserLanguages;
 
            string resxPath = string.Format(@"{0}\{1}.resx", filePath, viewName);
 
            foreach (var lang in langs)
            {
                if (File.Exists(string.Format(@"{0}\{1}.{2}.resx", filePath, viewName, lang)))
                {
                    resxPath = string.Format(@"{0}\{1}.{2}.resx", filePath, viewName, lang);
                    break;
                }
            }
 
            string result = "";
 
            ResXResourceReader reader = new ResXResourceReader(resxPath);
            var entry = reader.Cast<DictionaryEntry>().FirstOrDefault<DictionaryEntry>(x => x.Key.ToString() == key);
 
            if (entry.Value != null)
            {
                result = (string)entry.Value;
            }
 
            return result;
        }
    }

這個方案應該只能算是一個參考原型,還有很多可以改進的地方,比如方法裡沒有使用CultureInfo之類的東西,因為我們公司通常的方案是語言
隨著瀏覽器的語言設定來的,為了測試簡單點,我只是根據Request裡面的UserLanguages來確定顯示何種語言,另外,每次都new一個
Reader是否會對效能帶來較大的影響也未經測試,不過最基本的功能有了,使用該方案,可以像在WebPage裡面一樣方便的使用資源檔了。

對了,差點忘了很重要的內容,如何使用該方法:

@Html.Lang("Test")

即可,"Test"為資源的Key

值的一提的是,這個LocalizationHelpers類型命名空間需為System.Web.Mvc

如果大家有更好的方案,請通知我,謝謝

修改:在樣本源碼中LocalizatioinHelpers第16行錯誤,

var filePath =
htmlhelper.ViewContext.HttpContext.Server.MapPath(viewPath.Substring(0,
viewPath.Length - viewPath.LastIndexOf('/'))) + "App_LocalResources";

修正如下:

var filePath = htmlhelper.ViewContext.HttpContext.Server.MapPath(viewPath.Substring(0, viewPath.LastIndexOf('/') + 1)) + "App_LocalResources";

範例程式碼

3月22日整理:實用樣本請參考:這裡

支援多國語言基本上是一個成熟產品必須支援的功能,但是直到想用這個功能時,發現居然找不到解決方案(很吃驚,真的沒有提供嗎?),於是在網上搜尋了好久,發現兩種心儀的方案:

1: ASP.NET MVC 多語言解決方案

2: ASP.NET MVC - Localization Helpers

這兩種方案都是針對WebFormViewEngine的,對於想使用Razor的我來說,修改是必然的了

先說說第二種,這個方法貌似核心是使用了HttpContext.GetLocalResourceObject()方法。但是問題在於在使用
GetLocalResourceObject()方法時,需要提供一個參數virtualPath,這個參數花了好久心思沒有成功,關鍵是上面有句代碼
老是會拋異常:

ResourceExpressionFields fields = (ResourceExpressionFields)builder.ParseExpression(expression, typeof(string), context);

總是說expression不對之類的,我猜應該是在WebFormViewEngine裡面綁定運算式不能在Razor裡使用的原因吧,但是我偷
偷的類比了一個WebForm式的綁定運算式,依然不能執行通過。而且官方也沒有提供一個完整的樣本,時間關係我也不想研究了,如果有人在Razor上試
驗成功了,麻煩留個言。

再來說第一種,個人感覺習慣上這個除了一樣,其它的啥都好,哪一樣呢,就是必須使用RexGen來編譯.resx檔案,使其成
為.resources檔案,然後再去使用。在以前使用WebPage時是沒有這一步的,多一步總沒有少一步來的方便,因此又開啟MSDN來看看,一看發
現一個類型:ResXResourceReader,從這個類型的名稱上看就是一個好東西,但是在寫代碼時居然發現找不到該類型?再仔細一看,原來這個類
型居然是定義在System.Windows.Forms命名空間中的,在Web程式中加入System.Windows.Forms.dll引用總感覺
是怪怪的,但是想想都是.NET的標準類庫,加起來應該也沒有太大的影響,再說還不知道加進來能不能用。

於是參照第一種解決方案做出一個助手類:

    public static class LocalizationHelpers
    {
        public static string Lang(this HtmlHelper htmlhelper, string key)
        {
            var viewPath = (htmlhelper.ViewContext.View as BuildManagerCompiledView).ViewPath;
            var viewName = viewPath.Substring(viewPath.LastIndexOf('/'), viewPath.Length - viewPath.LastIndexOf('/')).TrimStart('/');
            var filePath = htmlhelper.ViewContext.HttpContext.Server.MapPath(viewPath.Substring(0, viewPath.LastIndexOf('/') + 1)) + "App_LocalResources";
            var langs = htmlhelper.ViewContext.HttpContext.Request.UserLanguages;
 
            string resxPath = string.Format(@"{0}\{1}.resx", filePath, viewName);
 
            foreach (var lang in langs)
            {
                if (File.Exists(string.Format(@"{0}\{1}.{2}.resx", filePath, viewName, lang)))
                {
                    resxPath = string.Format(@"{0}\{1}.{2}.resx", filePath, viewName, lang);
                    break;
                }
            }
 
            string result = "";
 
            ResXResourceReader reader = new ResXResourceReader(resxPath);
            var entry = reader.Cast<DictionaryEntry>().FirstOrDefault<DictionaryEntry>(x => x.Key.ToString() == key);
 
            if (entry.Value != null)
            {
                result = (string)entry.Value;
            }
 
            return result;
        }
    }

這個方案應該只能算是一個參考原型,還有很多可以改進的地方,比如方法裡沒有使用CultureInfo之類的東西,因為我們公司通常的方案是語言
隨著瀏覽器的語言設定來的,為了測試簡單點,我只是根據Request裡面的UserLanguages來確定顯示何種語言,另外,每次都new一個
Reader是否會對效能帶來較大的影響也未經測試,不過最基本的功能有了,使用該方案,可以像在WebPage裡面一樣方便的使用資源檔了。

對了,差點忘了很重要的內容,如何使用該方法:

@Html.Lang("Test")

即可,"Test"為資源的Key

值的一提的是,這個LocalizationHelpers類型命名空間需為System.Web.Mvc

如果大家有更好的方案,請通知我,謝謝

修改:在樣本源碼中LocalizatioinHelpers第16行錯誤,

var filePath =
htmlhelper.ViewContext.HttpContext.Server.MapPath(viewPath.Substring(0,
viewPath.Length - viewPath.LastIndexOf('/'))) + "App_LocalResources";

修正如下:

var filePath = htmlhelper.ViewContext.HttpContext.Server.MapPath(viewPath.Substring(0, viewPath.LastIndexOf('/') + 1)) + "App_LocalResources";

範例程式碼

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.