全球化的網站不免都要做多國語言,ASP.NET Core 的多國語言設定方式跟 ASP.NET MVC 有很大的落差。 本篇將介紹 ASP.NET Core 多國語言設定方式。
1. 安裝 NuGet 套件 要在 ASP.NET Core 使用多國語言,需要安裝 Microsoft.AspNetCore.Localization
套件。 在此範例中我還需要從 Routing 抓取語系的資訊,所以要再安裝 Microsoft.AspNetCore.Localization.Routing
套件。
Microsoft.AspNetCore.Localization.Routing
也可以自己實作。
2. 建立多國語言檔 在網站目錄中建立 Resources 的資料夾,在裡面新增資源檔 *.resx
。如下:
ASP.NET Core 語系檔命名規則必須 要與 Controllers / Views / Models 相互對應。如下:
Resources\Controllers\HomeController.en-GB.resx 或 Resources\Controllers.HomeController.en-GB.resx Resources\Controllers\HomeController.zh-TW.resx 或 Resources\Controllers.HomeController.zh-TW.resx Resources\Views\Home\Index.en-GB.resx 或 Resources\Views.Home.Index.en-GB.resx Resources\Views\Home\Index.zh-TW.resx 或 Resources\Views.Home.Index.zh-TW.resx 多國語言檔建立規則跟 ASP.NET MVC 有很大的差別。
*.resx
檔案必須 對應使用的路徑位置。*.resx
檔案必須 要帶語系在後綴。如:*.en-GB.resx
。3. Startup 在 Startup 註冊多國語言需要服務,以及修改多國語的 Routing 方式。如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 using Microsoft.AspNetCore.Builder;using Microsoft.AspNetCore.Mvc.Razor;using Microsoft.Extensions.DependencyInjection;namespace MyWebsite { public class Startup { public void ConfigureServices (IServiceCollection services ) { services.AddLocalization(options => options.ResourcesPath = "Resources" ); services.AddMvc() .AddViewLocalization() .AddDataAnnotationsLocalization(); } public void Configure (IApplicationBuilder app ) { app.UseMvc(routes => { routes.MapRoute( name: "default" , template: "{culture=en-GB}/{controller=Home}/{action=Index}/{id?}" ); }); } } }
AddLocalization
是主要的多國語言服務,ResourcesPath 是指定資源檔 的目錄位置。AddViewLocalization
是為了在 cshtml 中使用多國語言,如果沒有需要在 cshtml 中使用多國語言,可以不需要註冊它。AddDataAnnotationsLocalization
是為了在 Model 中使用多國語言,如果沒有需要可以不需要註冊它。MapRoute
我在 Routing 中增加 culture 語系資訊,用來判斷多國語言。 如果不想用 Routing 的方式,也可以改用 QueryString 帶入語系資訊。4. Middleware 建立一個 CultureMiddleware 來包裝 Localization 的 Middleware,因為我要順便做支援語言的管理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 using Microsoft.AspNetCore.Builder;using Microsoft.AspNetCore.Localization;using Microsoft.AspNetCore.Localization.Routing;using System.Collections.Generic;using System.Globalization;using System.Linq;namespace MyWebsite.Middlewares { public class CultureMiddleware { private static readonly List<CultureInfo> _supportedCultures = new List<CultureInfo> { new CultureInfo("en-GB" ), new CultureInfo("zh-TW" ) }; private static readonly RequestLocalizationOptions _localizationOptions = new RequestLocalizationOptions() { DefaultRequestCulture = new RequestCulture(_supportedCultures.First()), SupportedCultures = _supportedCultures, SupportedUICultures = _supportedCultures, RequestCultureProviders = new [] { new RouteDataRequestCultureProvider() { Options = _localizationOptions } } }; public void Configure (IApplicationBuilder app ) { app.UseRequestLocalization(_localizationOptions); } } }
每個 Requset 都會執行 RequestCultureProviders 中的 CultureProvider,用來判斷語系資訊,套用正確的資源檔。Microsoft.AspNetCore.Localization
套件支援的 CultureProvider 有三種:
QueryStringRequestCultureProvider
從 QueryString 判斷語系資訊。CookieRequestCultureProvider
從 Cookie 判斷語系資訊。AcceptLanguageHeaderRequestCultureProvider
從 HTTP Header 判斷語系資訊。而我是用 Routing 判斷語系資訊,以上三種都不合我用,所以才需要另外安裝 Microsoft.AspNetCore.Localization.Routing
,使用 RouteDataRequestCultureProvider。
把 CultureMiddleware 註冊在需要用到的 Controller 或 Action。如下:
1 2 3 4 5 [MiddlewareFilter(typeof(CultureMiddleware)) ] public class HomeController : Controller { }
通常 ASP.NET 網站會伴隨著 API,API 不需要語系資訊,所以不建議註冊在全域。
5. 使用多國語言 5.1. Controller 在 Controller 要使用多國語言的話,需要在建構子加入 IStringLocalizer 參數,執行期間會把 Localizer 的實體注入近來。 把 Resource Key 丟入 Localizer,就可以得到值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [MiddlewareFilter(typeof(CultureMiddleware)) ] public class HomeController : Controller { private readonly IStringLocalizer _localizer; public HomeController (IStringLocalizer<HomeController> localizer ) { _localizer = localizer; } public IActionResult Content () { return Content($"CurrentCulture: {CultureInfo.CurrentCulture.Name} \r\n" + $"CurrentUICulture: {CultureInfo.CurrentUICulture.Name} \r\n" + $"{_localizer["Hello" ]} " ); } }
5.2. View 要在 cshtml 使用多國語言的話,要先在 Setup 的 Services 中加入 ViewLocalization。 注入 IViewLocalizer,把 Resource Key 丟入 Localizer,就可以得到值。
1 2 3 4 5 6 7 8 9 @using System.Globalization @using Microsoft.AspNetCore.Mvc.Localization @using MyWebsite.Models @inject IViewLocalizer Localizer CurrentCulture: @CultureInfo.CurrentCulture.Name <br /> CurrentUICulture: @CultureInfo.CurrentUICulture.Name <br /> @Localizer["Hello"]<br />
5.3. Model 要在 Model 使用多國語言的話,要先在 Setup 的 Services 中加入 DataAnnotationsLocalization。
1 2 3 4 5 public class SampleModel { [Display(Name = "Hello" ) ] public string Content { get ; set ; } }
1 2 3 4 5 6 7 8 @using System.Globalization @using MyWebsite.Models @model SampleModel CurrentCulture: @CultureInfo.CurrentCulture.Name <br /> CurrentUICulture: @CultureInfo.CurrentUICulture.Name <br /> @Html.DisplayNameFor(m => m.Content)<br />
執行結果
程式碼下載 asp-net-core-localization
參考 ASP.NET Core Globalization and localization