Blazor Server App 實作多國語系紀錄
Localization, Globalization, NET5, NET6
補充 on 2024-4-18
此篇多國語系實作適用於 .NET5, NET6。 .NET8 的多國語系實作方式改變了,請參考: ASP.NET Core Blazor 全球化和當地語系化 8.0。
先總結成果
需安裝套件
Install-Package Microsoft.Extensions.Localization
調整相關檔案清單
appsettings.json
決定要支援那些語系。
Startup.cs
設定多國語系
Language.cshtml.cs
切換多國語系,在此用 Cookie 存放現在選取的語系。
Shared/ChooseLanguage.razor
切換語系的UI介面
Resource 目錄
設定各語系資料。
各元件各別設定自己的語系。
應用
Pages/
Your Razor Component.razor
未完事項
DataAnnotations 之 Form Validation 在地中文化試不出來。
appsettings.json
{
"AllowedHosts": "*",
"Cultures": { ///--- 決定要支援的語系
"en-US": "USA",
"es-ES": "Spain",
"es-MX": "Mexico",
"zh-TW": "台灣"
}
}
Startup.cs
public class Startup
{
...
public void ConfigureServices(IServiceCollection services)
{
///# for 多國語系
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.Configure<RequestLocalizationOptions>(options =>
{
// 自 appsettings 取得要支援的語系
var cultures = Configuration.GetSection("Cultures").GetChildren().ToDictionary(x => x.Key, x => x.Value);
var supoortedCultures = cultures.Keys.ToArray();
// 加入組態
options.AddSupportedCultures(supoortedCultures);
options.AddSupportedUICultures(supoortedCultures);
options.SetDefaultCulture("zh-TW");
options.DefaultRequestCulture = new Microsoft.AspNetCore.Localization.RequestCulture("zh-TW");
});
services.AddRazorPages();
services.AddServerSideBlazor();
...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseStaticFiles();
///# for 多國語系 - 啟用
app.UseRequestLocalization();
app.UseRouting();
...
}
}
Language.cshtml.cs
@page
@model BlazorServerApp.Pages.LanguageModel
@* 這是虛畫面 *@
<h2>Language</h2>
<p>用於多國語系切換。</p>
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace BlazorServerApp.Pages
{
public class LanguageModel : PageModel
{
/// 切換語系
public IActionResult OnGet(string culture, string redirectUrl)
{
if (culture != null)
{
/// 設定多國語系到 Cookie 指定的位置與編碼。
HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(culture)));
}
/// 將依選取語系刷新回原畫面。
return LocalRedirect(redirectUrl);
}
}
}
ChooseLanguage.razor
@inject NavigationManager navMan
@inject IConfiguration cfgSvc
@if (cultures != null)
{
@* 語系切換介面 *@
<form class="form-inline">
<select class="form-control mr-2" @bind="selectedCulture">
<option>選取…</option>
@foreach (var culture in cultures)
{
<option value="@culture.Key">@culture.Value</option>
}
</select>
<button class="btn btn-outline-primary" @onclick="RequestCultureChange">Change</button>
</form>
}
@code{
string selectedCulture;
Dictionary<string, string> cultures;
protected override void OnInitialized()
{
selectedCulture = System.Threading.Thread.CurrentThread.CurrentCulture.Name;
cultures = cfgSvc.GetSection("Cultures").GetChildren().ToDictionary(x => x.Key, x => x.Value);
}
void RequestCultureChange()
{
if (String.IsNullOrWhiteSpace(selectedCulture))
return;
var redirectUrl = new Uri(navMan.Uri).GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var queryString = $"?culture={Uri.EscapeDataString(selectedCulture)}&redirectUrl={Uri.EscapeDataString(redirectUrl)}";
navMan.NavigateTo($"/Language{queryString}", forceLoad: true);
}
}
Resource 目錄
放置各語系資料,最主要的工作內容之一。如圖例:

應用
可以用 CultureInfo
類別取得現在的語系。
使用 IStringLocalizer<T>
拿取目標語系資料,可以一次拿多份語系資料。
其他日期、時間的預設顯示格式也會依語系文化不同而不同。
@using Microsoft.Extensions.Localization
@using System.Globalization
@page "/culture"
@inject IStringLocalizer<Pages.A04Culture._PageCtx> localizer
@inject IStringLocalizer<App> locCommon
<h1>語系與文化資訊</h1>
@* === 測試語系是否成功切換, 日期時間格式是否依語系不同而改變 === *@
<h2>@localizer["您好"]</h2>
<h2>@DateTime.Now.ToShortDateString() @DateTime.Now.ToShortTimeString()</h2>
<h2>@DateTime.Now.ToLongDateString() @DateTime.Now.ToLongTimeString()</h2>
@* === 測試參數化訊息的語系切換 === *@
<p>@String.Format(localizer["模擬錯誤訊息:{0}"], simsErrMsg)</p>
@* === 可以用 CultureInfo 類別取得現在的語系 === *@
<table>
<tr>
<th>Current Culture</th>
<td>@CultureInfo.CurrentCulture</td>
</tr>
<tr>
<th>Current UI-Culture</th>
<td>@CultureInfo.CurrentUICulture</td>
</tr>
<tr>
<th>Default Thread Current Culture</th>
<td>@CultureInfo.DefaultThreadCurrentCulture</td>
</tr>
<tr>
<th>Default Thread Current UI-Culture</th>
<td>@CultureInfo.DefaultThreadCurrentUICulture</td>
</tr>
</table>
@code{
string simsErrMsg = "老婆永遠是對的。";
protected override void OnAfterRender(bool firstRender)
{
base.OnAfterRender(firstRender);
}
}
參考資料
EOF
Last updated