若是要支持Blazor WebAssembly的本地化,應該如何實現呢?下面,咱們就按照本地化問題操做中所涉及的全部主要問題以提問的方式進行說明。html
1.本地化的核心原理是什麼?瀏覽器
答:就是顯式地在Program.Main方法中設置 CultureInfo.DefaultThreadCurrentCulture和CultureInfo.DefaultThreadCurrentUICulture這兩個屬性。服務器
2. 用戶選擇的本地化語言設置的值存放在哪裏?網絡
有三種主要方式,第一種是存放在本地,這種優勢是不涉及與服務器的網絡交互,能節省一點的服務器端和網絡的資源消耗,缺點是,換了客戶端就要從新設置。async
第二種是存放在服務器端。這種方式優勢是語言本地化設置不隨着客戶端的變動而變動,客戶體驗好,缺點就是與服務器有資源消化,在服務端不但要寫Api接口,還要存儲,還要考慮負載等一系列問題。測試
第三種,就是將前面兩種方式都結合起來,服務端和客戶端都存儲,若是換了客戶端,客戶端沒有存儲,就去服務端查找相應設置。客戶端有,就不去查詢服務器設置。這種方式結合了前面兩種的優勢,算是比較完美的方案。ui
由於第一種方式的影響甚微,相對一直使用一種客戶端的用戶來講,用戶換客戶端的機會相對較少。一般對於用戶來講,也是能夠接受的,我在這裏採起第一種方式首先予以說明。spa
3. 那麼咱們要將本地化設置要存放在本地瀏覽器的什麼地方,如何實現呢?code
答案是localStorage,咱們只須要在wwwroot/index.html文件中加入一段js代碼,就能夠搞定這一步。htm
<script> window.blazorCulture = { get: () => window.localStorage['BlazorCulture'], set: (value) => window.localStorage['BlazorCulture'] = value }; </script>
4. 如何將第三個問題存放的設置取出來,賦給第一步說到的兩個屬性,以便本地化起做用?
經過在Program.Main方法中,能夠經過C#與js的交互來獲取到相應設置。只要在host.RunAsync()以前調用下面定義的這個方法就完成了相關操做:
static async Task GetCulture(WebAssemblyHost host) { var jsInterop = host.Services.GetRequiredService<IJSRuntime>(); var result = await jsInterop.InvokeAsync<string>("blazorCulture.get"); if (result != null) { var culture = new CultureInfo(result); CultureInfo.DefaultThreadCurrentCulture = culture; CultureInfo.DefaultThreadCurrentUICulture = culture; } }
調用上段方法具體爲:
builder.Services.AddApiAuthorization(); var host = builder.Build(); await GetCulture(host); await host.RunAsync();
5.第四個問題說到了本地化設置的獲取,沒有提到設置並保存,那麼應該怎樣設置和保存?
要選擇和設置本地化語言,固然就要給用戶提供交互UI界面,要提供這樣的界面,能夠定義一個Blazor組件,如命名爲CultureSelector.razor,將其添加到Shared文件夾中。
首先,這個組件要選擇語言選項,那麼確定須要一個選擇列表來列出相關語言以便供選擇,這就用到了html中的<select>標籤。
再者,還要將用戶所選選項值保存,又要調用第三個問題中js代碼,這就涉及到了C#與js的交互。
最後,設置完了,並保持了,你須要刷新你的頁面,以便你的本地化設置生效,並呈現給用戶,這就須要強制刷新。
上面所涉及到的,都須要在CultureSelector.razor這個組件中完成,具體的代碼以下所示。最後,將組件的標籤<CultureSelector />寫在你的目標頁面的具體位置以給用戶呈現。
@using System.Globalization @inject IJSRuntime JSRuntime @inject NavigationManager Nav <select @bind="Culture"> @foreach (var culture in supportedCultures) { <option value="@culture">@culture.Name.Split()[0]</option> } </select> @code { CultureInfo[] supportedCultures = new[] { new CultureInfo("en-US"), new CultureInfo("zh-CN"), }; CultureInfo Culture { get => CultureInfo.CurrentCulture; set { if (CultureInfo.CurrentCulture != value) { var js = (IJSInProcessRuntime)JSRuntime; js.InvokeVoid("blazorCulture.set", value.Name); Nav.NavigateTo(Nav.Uri, forceLoad: true); } } } }
6. 頁面的內容的本地化資源如何存放?
內容的本地化資源,只須要你添加與你要本地化的razor頁面同名的.resx資源文件,並在其中定義你的本地化內容便可。例如:我要本地化Pages文件夾中BranchPage.razor頁面,默認內容是英文的,我如今要將其支持能夠本地化爲中文,那我就添加資源文件名BranchPage.zh-CN.resx。並在裏面將英文做爲鍵,中文做爲值進行存放便可。若是做爲鍵,英文太長的話,能夠定義關鍵字做爲鍵,而且須要你再添加默認的BranchPage.resx資源文件做爲英文資源文件。
7. 內容本地化資源信息存好了,如何在頁面中調用?
仍是以上面的BranchPage.razor爲例,要在其中調用資源文件中的信息,就須要如下幾步:
(1)在Program.Main中添加本地化服務
builder.Services.AddLocalization();
(2)在BranchPage.razor中進行下列本地化注入。
@inject IStringLocalizer<BranchPage> localizer
(3)用上面定義的localizer來進行調用
<tr> <th>@localizer["ID"]</th> <th>@localizer["Code"]</th> <th>@localizer["Name"]</th> <th>@localizer["Description"]</th> </tr>
至此,涉及本地化的主要步驟和關鍵點就完成了,你就能夠測試您的代碼了。