(簡單描述開發環境)
使用環境: ASP.Net Core 2.X
開發工具: VSCode
範例網址: 多語範例Github
在csproj中的PackageReference有”Microsoft.AspNetCore.All”的套件引用的話,預設就會有語系功能了,只需要再執行以下設定就好了!
如果沒有引用All套件,則需要手動安裝以下套件:

  1. Microsoft.AspNetCore.Mvc.Localization: 語系的預設套件
  2. Microsoft.AspNetCore.Localization.Routing: 可以使用在URL的語系套件

今天來個實用的教學好了,前陣子在網站開發網多國語系,然後老闆就要我做一個功能。
直接來看例子好了:

  1. <<domain>>/ => 進入預設語系(zh)
  2. <<domain>>/zh => 進入預設語系(zh)
  3. <<domain>>/home/contact => 進入預設語系(zh)的contact頁面
  4. <<domain>>/en => 進入預設語系(en)
  5. <<domain>>/en/home/contact => 進入預設語系(en)的contact頁面
    所以我因此陷入了深深的思考老闆就是一個奇怪的生物

1. 設定好Resources

設定Resources的位置(這個可以自定義,我是設定在根目錄的“Resources”文件夾中
接下來新增controller為基底的Resource檔案,必須符合以下的規則:
– Resources/Controller/HomeController.resx
– Resources/Controller/HomeController.en.resx
– Resources/Controller.HomeController.en.resx
可以使用文件夾(/)的方式或是檔案(.)的方式來區分。
resx為副檔名。
en為語系名稱,不輸入則是預設的語系。
詳細的設定方法請到微軟的教程文件中去做參考,鏈接會放在下方

再來是共享的Resource資源檔案,在Resources文件夾裡面的建立一個SharedResources資源檔
– Resources/SharedResources.resx
– Resources/SharedResources.en.resx
規則跟上方的類似哦

SharedResources檔案需要加一個Class才能正常使用,建立在Resources文件夾中:
1
2
3
4
5
6
7
//不需要加入任何的屬性或function,namespace也不需要在Resources中
namespace core_localization
{
public class SharedResources
{
}
}

***因為resx是原本在VS使用的資源檔,VSCode無法自動產生,也沒有相關套件。。。
***但是可以直接複製其他的resx檔案後再修改,修改不難,稍微看一看就會知道了

2. 設定StartUp檔案

在根目錄的StartUp.cs的ConfigureServices function加入以下程式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//設定多語的設定項,方便在其他檔案中可以取得一樣的設定項
services.Configure<RequestLocalizationOptions>(opts =>
{
IList<CultureInfo> cultures = new List<CultureInfo>{
new CultureInfo("en"),
new CultureInfo("zh"),
};
opts.DefaultRequestCulture = new RequestCulture("zh");
opts.SupportedCultures = cultures;
opts.SupportedUICultures = cultures;
opts.FallBackToParentCultures = true;
opts.FallBackToParentUICultures = true;
opts.RequestCultureProviders = new[]{
new RouteDataRequestCultureProvider //使用URL的路徑作為語系的設定
{
Options = opts
}
};
});
//設定Resources的文件夾路徑(必須與上方Resources文件夾一樣)
services.AddLocalization(opts => opts.ResourcesPath = "Resources");//指定Resources的路徑
services.AddMvc()
.AddViewLocalization(); //在Razor中使用Localizer時,需要加入這行

再來在Configure function中實際使用:

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
//取得上方設定好的設定項物件
var localizationOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
//語系設定項的使用,預設URL可以套用的語系項
app.UseRequestLocalization(localizationOptions.Value);
app.UseMvc(routes =>
{
//預設的URL路徑
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}",
defaults: new { culture = "zh" }); //若URL沒有語系,預設zh語系
//對照語系的URL路徑
routes.MapMiddlewareRoute("{culture=zh}/{*mvcRoute}", subApp =>
{
//語系設定項的使用,用於子路徑可以套用語系
subApp.UseRequestLocalization(localizationOptions.Value);
//對照有語系的URL路徑
subApp.UseMvc(mvcRoutes =>
{
mvcRoutes.MapRoute(
name: "default",
template: "{culture=zh}/{controller=Home}/{action=Index}/{id?}");
});
});
});

3. 實際使用咯!

在Controller中可以以DependencyInjection收到語系物件哦!

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
public class HomeController : Controller
{
//這個會自動對照到Resources/Controllers/HomeController.resx檔案
public readonly IStringLocalizer<HomeController> _localizer;
//這個會自動對照到Resources/SharedResources.resx資源檔
public readonly IStringLocalizer<SharedResources> _sharedLocalize;
public readonly ILogger<HomeController> _logger;
public HomeController(IStringLocalizer<HomeController> localizer,
IStringLocalizer<SharedResources> sharedLocalizer,
ILogger<HomeController> logger)
{
_localizer = localizer;
_sharedLocalize = sharedLocalizer;
_logger = logger;
}
public IActionResult Index()
{
//使用相關物件就可以取得不同語系的文字咯!
//"Hello" 就可以對照到Resources裡面的"Hello"key
ViewData["hello home"] = _localizer["Hello Home"];
ViewData["hello"] = _sharedLocalize["Hello"];
return View();
}
//.......
}

在CsHtml中直接使用:

1
2
3
4
5
6
@* 直接在頁面注入 *@
@inject Microsoft.AspNetCore.Mvc.Localization.IHtmlLocalizer<HomeController> htmlLocalizer;
@inject Microsoft.Extensions.Localization.IStringLocalizer<HomeController> _localizer;

@* 頁面使用方法 *@
@_localizer["Hello"]

這樣就可以基本使用了~
過幾天再寫一些開發時遇到的陷阱,敬請期待!

陷阱!

表示發現了輸入/fake-culture/home/contact,正式來說,沒有fake-culture這個語系,所以應該需要自動跳轉到/zh/home/contact
但是他會抓到fake-culture,然後直接給預設的zh語系,然後URL還是/fake-culture/home/contact。。。
之後再想辦法去抓一下正確的語系好了。。。這個陷阱就留給各位讀者去解決再互相交流一下好了

後續: MVC-多國語系-陷阱篇

知識鏈接

微軟官方多語文檔
ASP.NET Core Localization Deep Dive
John Wu-多國語言教學