【Blazor】| 總結/Edison Zhou
大家好,我是Edison。
很久沒有更新Blazor這個系列了,在上一篇我提到了接下來會介紹一下如何在Blazor中實作多語言,這就安排上了。
多語言+本地化的背景
在Web應用開發中,我們可能會有一些需要多語言+本地化的場景,特别在一些國際化的外資企業當中特别常見。例如,Edison所在的IT開發團隊,就需要英語,中文和德語三種語言的支援,使用者可以通過“切換頁面語言”這個功能來切換到适合他的語言來浏覽頁面的内容。是以,為Web應用提供多語言,頁面内容可以本地化,會擴充我們的IT系統閱聽人範圍,提升一點使用者體驗。
是以,如何在Blazor中實作多語言+本地化就被提上議程。
一些基本的名詞術語
為了更好地了解下面的内容,我們先來了解一下行業内通用的名詞術語:
- Globalization (G11N):全球化,即使應用支援不同語言和區域的過程。G11N 是首字母、尾字母和它們之間字母的個數組成的,下同,不再贅述。
- Localization (L10N):本地化,即針對特定語言和區域自定義全球化應用的過程。
- Internationalization (I18N):國際化,又稱為多語言,包含了全球化和本地化。
- Culture:區域性,即一種語言文化或區域。
- Neutral Culture:非特定區域性,即具有指定語言但不具有區域的區域性。例如“zh”、“en”,僅僅表示中文或英文,并沒有包含指定地區,如大陸、香港、台灣等。
- Specific Culture: 特定區域性,即具有指定語言和區域的區域性。例如“zh-CN”、“zh-HK”。
- Parent Culture: 父區域性,例如“zh”就是“zh-CN”和“zh-HK”的父區域性。
在Blazor中實作本地化的方式
在Blaozr中實作本地化的方式,其實也就是ASP.NET Core提供的那些本地化工具:
- IStringLocalizer
- IStringLocalizerFactory
- IHtmlLocalizer
- IViewLocalizer
在Blazor中,我們最常用的就是IStringLocalizer,它可以在運作時提供區域性資源,使用非常簡單,就像操作字典一樣,提供一個 Key,就能擷取到指定區域的資源。
接下來,我就以IStringLocalizer為例,介紹如何通過它來在Blazor應用中實作多語言和本地化。
在Blazor中實作本地化的步驟
(1)準備工作
假設我們已經有了一個Blazor應用程式,并且有一個Home.razor的頁面,需要支援中文(預設語言)、英語和德語。
(2)建立三個資源檔案
在根目錄下建立一個Resources目錄,再建立一個Pages子目錄,然後再建立三個resx資源檔案。這裡我們可以使用一個資源檔案來覆寫所有頁面的本地化内容,也可以針對多個頁面配置多個資源檔案。為了示範,這裡隻有一個資源檔案Home.resx應對示範頁面Home.razor。
key:HelloWorldTip, value: 你好,世界 -- 中文 key:HelloWorldTip, value: Hello, World! -- 英語 key:HelloWorldTip, value: Hallo, welt! -- 德語
補充:如果你習慣使用json作為資源檔案,也可以使用My.Extensions.Localization.Json 這個包來将resx換為json檔案。
(3)在Programs.cs中注冊和使用本地化
添加本地化服務,并指向我們剛剛建立的Resources目錄,并聲明系統需要支援三種語言,中文為預設的語言。
var builder = WebApplication.CreateBuilder(args); ...... // Add Localization builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); var app = builder.Build(); ...... app.MapControllers(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host"); // Use Localization const string CULTURE_CHINESE = "zh-CN"; const string CULTURE_ENGLISTH = "en-US"; const string CULTURE_GERMAN = "de-DE"; app.UseRequestLocalization(options => { var cultures = new[] { CULTURE_CHINESE, CULTURE_ENGLISTH, CULTURE_GERMAN }; options.AddSupportedCultures(cultures); options.AddSupportedUICultures(cultures); options.SetDefaultCulture(CULTURE_CHINESE); // 當Http響應時,将 目前區域資訊 設定到 Response Header:Content-Language 中 options.ApplyCurrentCultureToResponseHeaders = true; }); ......
(4)在_Imports.razor中添加全局注入
為了友善後續的使用,我們直接将IStringLocalizer和NavigationManager進行全局的注入。
...... @using Microsoft.AspNetCore.Localization @using System.Globalization @inject IStringLocalizer<Home> _translator; @inject NavigationManager _navigation; ......
(5)建立一個CultureController用于Culture的切換
為了讓頁面上的語言切換能夠更新系統的目前Culture,我們讓其通過調用API的方式來實作。
namespace EDT.BlazorServer.App.Controllers { [Route("[controller]/[action]")] public class CultureController : Controller { public IActionResult Set(string culture, string redirectUri) { if (!string.IsOrEmpty(culture)) { HttpContext.Response.Cookies.Append( CookieRequestCultureProvider.DefaultCookieName, CookieRequestCultureProvider.MakeCookieValue( new RequestCulture(culture, culture)), new CookieOptions { Secure = true, HttpOnly = true }); } return LocalRedirect(redirectUri); } } }
(6)改造Home.razor讓其可以實作本地化
這裡我們在頁面上使用IStringLocalizer對象來實作一個内容的切換。
@page "/home" <PageTitle>Index</PageTitle> <h1>@_translator["HelloWorldTip"]</h1> <p> <label> Select your locale: <select @bind="Culture"> @foreach (var culture in supportedCultures) { <option value="@culture">@culture.DisplayName</option> } </select> </label> </p> @code { private CultureInfo[] supportedCultures = new[] { new CultureInfo("zh-CN"), new CultureInfo("en-US"), new CultureInfo("de-DE") }; protected override void OnInitialized() { Culture = CultureInfo.CurrentCulture; } public CultureInfo Culture { get => CultureInfo.CurrentCulture; set { if (CultureInfo.CurrentCulture != value) { var uri = new Uri(_navigation.Uri) .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped); var cultureEscaped = Uri.EscapeDataString(value.Name); var uriEscaped = Uri.EscapeDataString(uri); _navigation.NavigateTo( $"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}", forceLoad: true); } } } }
(7)效果示範
如下圖所示:
小結
本篇,我們在Blazor中通過IStringLocalizer來實作了多語言和本地化。但其實IStringLocalizer隻是ASP.NET Core中本地化實作方式的一種而已,關于更多全球化和本地化的内容,建議閱讀參考資料中的兩篇文章,特别是建軍兄最近整理的《了解ASP.NET Core - 全球化與本地化》值得一讀!
參考代碼
GitHub:https://github.com/EdisonChou/BlazorSamples/tree/main
參考資料
Microsoft,《ASP.NET Core Blazor 全球化與本地化》xiaoxiaotank,《了解ASP.NET Core - 全球化與本地化》(五星推薦)
年終總結:Edison的2021年終總結數字化轉型:我在傳統企業做數字化轉型C#刷題:C#刷劍指Offer算法題系列文章目錄.NET面試:.NET開發面試知識體系.NET大會:2020年中國.NET開發者大會PDF資料