.NET Core中本地化機(jī)制的深入講解
前言
ASP.NET Core中提供了一些本地化服務(wù)和中間件,可將網(wǎng)站本地化為不同的語(yǔ)言文化。
ASP.NET Core中我們可以使用Microsoft.AspNetCore.Localization庫(kù)來(lái)實(shí)現(xiàn)本地化。
在.NET Core 2.0以上版本, Microsoft.AspNetCore.Localization已經(jīng)包含在了Microsoft.AspNetCore.All中,所以我們并不需要手動(dòng)引入其他的類庫(kù)。
創(chuàng)建一個(gè)MVC網(wǎng)站
為了測(cè)試ASP.NET Core的本地化,我們首先在Visual Studio 2017中創(chuàng)建一個(gè)MVC項(xiàng)目LocalizationSample。
配置Startup類
ASP.NET Core中,如果希望啟動(dòng)本地化,首先需要在Startup類的ConfigureServices方法中使用services.AddLocalization添加本地化服務(wù)。
public void ConfigureServices(IServiceCollection services) { services.AddLocalization(o => { o.ResourcesPath = "Resources"; }); services.AddMvc(); }
在這個(gè)方法中,我們指定了文件夾Resources作為存放翻譯文件的目錄。
注: 如果不指定存放翻譯文件的目錄, ASP.NET Core會(huì)默認(rèn)從網(wǎng)站根目錄下讀取。
然后我們需要在Configure方法中添加本地化中間件。
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseStaticFiles(); IList<CultureInfo> supportedCultures = new List<CultureInfo> { new CultureInfo("en-US"), new CultureInfo("zh-CN"), }; app.UseRequestLocalization(new RequestLocalizationOptions { DefaultRequestCulture = new RequestCulture("en-US"), SupportedCultures = supportedCultures, SupportedUICultures = supportedCultures }); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
- app.UseRequestLocalization必須放置app.UseMvc之前
- DefaultRequestCulture參數(shù)指定了默認(rèn)的語(yǔ)言文化,即用戶不指定任何文化時(shí)的默認(rèn)語(yǔ)言文化
- SupportedCultures和SupportedUICultures是指定當(dāng)前應(yīng)用支持的所有語(yǔ)言文化
注: SupportedCultures指定的是數(shù)字和日期格式, SupportedUICultures指定的翻譯文件
添加資源文件
下面我們嘗試添加一個(gè)資源文件
- 首先我們創(chuàng)建一個(gè)Resources文件夾,這就是我們?cè)谇懊鍿tartup類中配置的目錄名。
- 然后我們?cè)赗esource文件夾中添加一個(gè)資源文件,并命名為Controllers.HomeController.zh-CN.resx。
- 在這個(gè)資源文件中,添加一個(gè)字段Hello, 并設(shè)置其值為“你好”。
在Controller中獲取本地化字符串
現(xiàn)在我們打開默認(rèn)生成的HomeController, 清空里面所有的action, 并添加一個(gè)新的action, 代碼如下:
public class HomeController : Controller { public HomeController() { } public IActionResult Hello() { return Content("Hello"); } }
啟動(dòng)項(xiàng)目之后訪問(wèn)/Home/Hello, 結(jié)果如下
下面我們修改HomeController的代碼, 來(lái)引入本地化字符串訪問(wèn)器
public class HomeController : Controller { private readonly IStringLocalizer<HomeController> _localizer; public HomeController(IStringLocalizer<HomeController> localizer) { _localizer = localizer; } public IActionResult Hello() { return Content(_localizer["Hello"]); } }
代碼解釋
- IStringLocalizer是一個(gè)本地化字符串訪問(wèn)器的泛型接口,這里我們通過(guò)依賴注入的方式在HomeController的構(gòu)造函數(shù)中將其注入
- 我們可以通過(guò)IStringLocalizer的屬性訪問(wèn)器獲取到對(duì)應(yīng)字段在不同語(yǔ)言下的文本。
最終效果
現(xiàn)在我們啟動(dòng)程序, 重新訪問(wèn)/Home/Hello, 結(jié)果如下
你會(huì)發(fā)現(xiàn)結(jié)果沒有變化,這是因?yàn)槟J(rèn)我們?cè)O(shè)置的語(yǔ)言文化是en-US, 但是我們之前沒有添加en-US的資源文件,所以程序就直接將訪問(wèn)的字段名輸出了。
現(xiàn)在我們修改URL, 訪問(wèn)/Home/Hello?ui-culture=zh-CN, 結(jié)果如下
我們期望的“你好”被正確輸出了,這說(shuō)明ASP.NET Core默認(rèn)支持在Url中以culture參數(shù)的形式設(shè)置當(dāng)前網(wǎng)站使用的語(yǔ)言文化。
資源文件命名
為什么我們之前添加了一個(gè)名為Controllers.HomeController.zh-CN.resx的資源文件,本地化字符串訪問(wèn)器IStringLocalizer就能定位到這個(gè)文件并讀取其中的字段屬性呢?
這是由ASP.NET Core資源文件的命名約定決定的。
ASP.NET Core資源文件的名稱由2部分組成:
- 去掉程序集名稱的完整類名
- 語(yǔ)言文化名稱
以前面的例子為例:
我們創(chuàng)建了一個(gè)本地化字符串訪問(wèn)器接口,它的泛型類型是HomeController, 其完整類名是LocalizationSample.Controllers.HomeController, 當(dāng)前程序集的名稱是LocalizationSample, 所以去掉程序集名稱之后,剩余部分是Controllers.HomeController。當(dāng)我們?cè)O(shè)置culture參數(shù)是zh-CN時(shí), ASP.NET Core查找的資源文件名是Controllers.HomeController.zh-CN.resx, 這正是我們前面添加的中文語(yǔ)言文化資源文件名。
如果你不喜歡這種方式,ASP.NET Core還提供了另外一種資源文件的組織方式
你可以Resources目錄下創(chuàng)建以下目錄結(jié)構(gòu)
Resources
Controllers
HomeController.zh-CN.resx
本地化字符串訪問(wèn)器也能自動(dòng)定位到這個(gè)文件。
默認(rèn)的語(yǔ)言文化提供器
ASP.NET Core的本地化中間件默認(rèn)支持3種語(yǔ)言文化提供器
- URL中的查詢字符串
- Cookie
- 請(qǐng)求頭
URL中的查詢字符串
ASP.NET Core會(huì)從URL中的culture參數(shù)中獲取當(dāng)前應(yīng)用使用的語(yǔ)言文化,這就是前面例子中,“你好”能正確輸出的原因
除了指定ui-culture參數(shù),你還可以使用culture參數(shù)指定當(dāng)前格式化時(shí)間,數(shù)字等所使用的語(yǔ)言文化。
?culture=zh-CN&ui-culture=zh-CN ?culture=zh-CN ?ui-culture=zh-CN
Tips: 當(dāng)只指定culture或ui-culture參數(shù)時(shí),ASP.NET Core會(huì)自動(dòng)將culture和ui-culture設(shè)置成一樣的。即?culture=zh-CN等同于?culture=zh-CN&ui-culture=zh-CN
Cookie
ASP.NET Core中還支持使用Cookie的方式設(shè)置當(dāng)前應(yīng)用使用的語(yǔ)言文化。默認(rèn)使用的Cookie名稱是.AspNetCore.Culture。
.AspNetCore.Culture的值格式如下
c=zh-CN|uic=zh-CN c=zh-CN uic=zh-CN
其中c表示culture, uic表示ui-culture。
下面我們使用Chrome的開發(fā)者工具, 為當(dāng)前網(wǎng)頁(yè)添加語(yǔ)言文化Cookie
然后我們?cè)L問(wèn)/Home/Hello, "你好"也被正確的輸出了
這說(shuō)明ASP.NET Core從Cookie中讀取到了語(yǔ)言文化配置
請(qǐng)求頭
除了URL查詢字符串和Cookie, ASP.NET Core還支持在請(qǐng)求頭中指定語(yǔ)言文化。請(qǐng)求頭中語(yǔ)言文化字段名稱是 Accept-Language。
Accept-Language的文檔,參見https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Accept-Language
這里我們使用Postman來(lái)測(cè)試一下,我們?cè)O(shè)置Accept-Language為zh-CN, zh;q=0.9, 結(jié)果如下
如何在View中使用本地化
除了Controller, 我們更多的是在View中使用本地化。
如果希望在View中使用本地化,首先需要在Startup類的ConfigureServices方法中啟用View本地化。
public void ConfigureServices(IServiceCollection services) { services.AddMvc() .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix); }
這里L(fēng)anguageViewLocationExpanderFormat支持2種方式,這個(gè)和前面Controller的本地化文件名稱約定類似
- Suffix, 例/Resources/Home/Hello.zh-CN.resx
- Path, 例/Resources/Home/zh-CN/Hello.resx
下面我們修改HomeController的代碼,Hello方法將返回一個(gè)View
HomeController
public IActionResult Hello() { //return Content(_localizer["Hello"]); return View(); }
Hello.cshtml
@{ ViewData["Title"] = "Hello"; } <h2>Good Bye</h2>
然后我們創(chuàng)建如下圖的目錄結(jié)構(gòu), 并創(chuàng)建資源文件Hello.zh-CN.resx, 并添加GoodBye字段,其值為"再見"
使用ViewLocalizer
ViewLocalizer類可以幫助我們?cè)赗azor視圖中使用本地化文本?,F(xiàn)在我們來(lái)修改Hello.cshtml, 在文件添加本地化引用,并注入一個(gè)ViewLocalizer對(duì)象
@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @{ ViewData["Title"] = "Hello"; } <h2>@Localizer["GoodBye"]</h2>
這里我們使用ViewLocalizer讀取了本地化文本,它的用法和IStringLocalier一樣,都是通過(guò)屬性訪問(wèn)器訪問(wèn)對(duì)應(yīng)字段的本地化文本。
最終效果
現(xiàn)在我們運(yùn)行程序并訪問(wèn)/Home/Hello, 結(jié)果如下
然后我們繼續(xù)訪問(wèn)/Home/Hello?ui-culture=zh-CN, 結(jié)果如下
本地化字符串讀取成功
本篇源代碼 https://github.com/lamondlu/aspnetcore_localizationsample (本地下載)
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
.NET 刷新頁(yè)面防止表單二次提交的實(shí)現(xiàn)方法
頁(yè)面上按鈕是服務(wù)器控件,現(xiàn)在刷新頁(yè)面要防止按鈕事件重復(fù)執(zhí)行。這篇文章給大家?guī)?lái)了.net刷新頁(yè)面防止表單二次提交的實(shí)現(xiàn)方法,非常不錯(cuò),感興趣的朋友一起看看吧2016-09-09深入理解__doPostBack 客戶端調(diào)用服務(wù)端事件
__doPostBack是一個(gè)純粹并且是非常簡(jiǎn)單的javascript函數(shù),大部分的頁(yè)面PostBack都是由它觸發(fā)的。2008-08-08Asp.net 頁(yè)面導(dǎo)航的幾種方法與比較 分享
在ASP.NET應(yīng)用中,Web表單之間的導(dǎo)航有多種方式:用超級(jí)鏈接,用Response.Redirect,用Server.Transfer,或者用Server.Execute。本文將分析這四種導(dǎo)航方式的異同及其優(yōu)缺點(diǎn),幫助你選擇最佳的導(dǎo)航方式。2013-07-07微信公眾平臺(tái)開發(fā)之處理圖片.Net代碼解析
這篇文章主要為大家詳細(xì)解析了微信公眾平臺(tái)開發(fā)之處理圖片.Net代碼,感興趣的小伙伴們可以參考一下2016-06-06asp.net 利用NPOI導(dǎo)出Excel通用類的方法
本篇文章主要介紹了asp.net 利用NPOI導(dǎo)出Excel通用類的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06使用ASP.NET MVC 4 Async Action+jQuery實(shí)現(xiàn)消息通知機(jī)制的實(shí)現(xiàn)代碼
這兩天在使用Asp.net MVC 4開發(fā)COMET消息通知機(jī)制,在后端使用異步線程對(duì)消息進(jìn)行訂閱,客戶端通過(guò)AJAX長(zhǎng)連接請(qǐng)求MVC中的ACTION2013-02-02asp.net微信開發(fā)(高級(jí)群發(fā)圖文)
這篇文章主要介紹了asp.net微信開發(fā)中有關(guān)高級(jí)群發(fā)圖文的相關(guān)內(nèi)容,需要的朋友可以參考下2015-11-11C# 沒有動(dòng)態(tài)的數(shù)組,可以用arraylist或list取代
C#里沒有動(dòng)態(tài)的數(shù)組,只能用arraylist或list取代。2009-06-06詳解.net core下如何簡(jiǎn)單構(gòu)建高可用服務(wù)集群
一說(shuō)到集群服務(wù)相信對(duì)普通開發(fā)者來(lái)說(shuō)肯定想到很復(fù)雜的事情,這篇文章主要介紹了詳解.net core下如何簡(jiǎn)單構(gòu)建高可用服務(wù)集群,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01