本地化
本地化是为给定语言和地区定制应用程序的过程。BootstrapBlazor
组件允许您将其 UI 元素转换为所需的语言。这包括按钮、过滤器操作符属性等文本。组件内部默认使用当前请求 UI
文化语言,本文将向您展示如何在应用程序中使用此功能:
本地化在组件中的工作原理
BootstrapBlazor
组件额外支持使用 Json
类型的键值信息作为资源文件,将其解析为 UI
中呈现的字符串。BootstrapBalzor 包自带中文(zh)、英语(en)两种资源文件。组件内置本地化语言回退机制,如请求文化为 zh-CN
时,如未提供相对应的文化资源文件时,内置逻辑通过父级文化进行尝试本地化,以 zh-CN
为例回退机制如下:
zh-CN
-> zh-Hans
-> zh
开启本地化功能
Server-Side App
1. 配置文件
通过 FallbackCultureName
设置回退文化信息,即未找到当前请求的文化信息时使用此配置文化,通过 SupportedCultures
设置支持的文化集合
{
"BootstrapBlazorOptions": {
"FallbackCultureName": "en-US",
"SupportedCultures": [
"zh-CN",
"en-US"
]
}
}
2. 启用 .NET 核心本地化服务
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// 增加 BootstrapBlazor 组件
services.AddBootstrapBlazor();
// 增加本地化服务配置信息
services.AddRequestLocalization<IOptions<BootstrapBlazorOptions>>((localizerOption, blazorOption) =>
{
var supportedCultures = blazorOption.Value.GetSupportedCultures();
localizerOption.SupportedCultures = supportedCultures;
localizerOption.SupportedUICultures = supportedCultures;
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// 启用本地化中间件并设置支持的文化信息
app.UseRequestLocalization(app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>()!.Value);
}
}
3. 实现 UI 本地化信息存储(例如,cookie)
[Route("[controller]/[action]")]
public class CultureController : Controller
{
public IActionResult SetCulture(string culture, string redirectUri)
{
if (!string.IsNullOrEmpty(culture))
{
HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture, culture)));
}
return LocalRedirect(redirectUri);
}
public IActionResult ResetCulture(string redirectUri)
{
HttpContext.Response.Cookies.Delete(CookieRequestCultureProvider.DefaultCookieName);
return LocalRedirect(redirectUri);
}
}
3. 添加允许用户更改本地化的 UI
@inherits BootstrapComponentBase
@inject IOptions<BootstrapBlazorOptions> BootstrapOptions
@inject NavigationManager NavigationManager
@inject ICultureStorage CultureStorage
<div @attributes="@AdditionalAttributes" class="@ClassString">
<label>请选择语言:</label>
<Select Value="@SelectedCulture" OnSelectedItemChanged="@SetCulture">
<Options>
@foreach (var kv in Configuration.GetSupportCultures())
{
<SelectOption Text="@kv.Key" Value="@kv.Value" />
}
</Options>
</Select>
</div>
@code {
private string? ClassString => CssBuilder.Default("culture-selector")
.AddClassFromAttributes(AdditionalAttributes)
.Build();
private string SelectedCulture { get; set; } = CultureInfo.CurrentUICulture.Name;
private async Task SetCulture(SelectedItem item)
{
if (CultureStorage.Mode == CultureStorageMode.Webapi)
{
// 使用 api 方式 适用于 Server-Side 模式
if (SelectedCulture != item.Value)
{
var culture = item.Value;
var uri = new Uri(NavigationManager.Uri).GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var query = $"?culture={Uri.EscapeDataString(culture)}&redirectUri={Uri.EscapeDataString(uri)}";
// use a path that matches your culture redirect controller from the previous steps
NavigationManager.NavigateTo("/Culture/SetCulture" + query, forceLoad: true);
}
}
else
{
var cultureName = item.Value;
if (cultureName != CultureInfo.CurrentCulture.Name)
{
await JSRuntime.InvokeAsync<string>(identifier: "$.blazorCulture.set", cultureName);
var culture = new CultureInfo(cultureName);
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;
NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true);
}
}
}
}
4. 附加 Json
资源文件
BootstrapBlazor
组件库即支持微软默认的 resx
格式资源,也支持嵌入式 json
格式资源,以及特定物理 json
文件
资源文件为合并关系,寻址规则优先级为
- 微软 resx 嵌入式资源文件
- 外置 json 物理文件
- json 嵌入式资源文件
- 内置 json 资源文件
public void ConfigureServices(IServiceCollection services)
{
services.AddBootstrapBlazor(setupAction: options =>
{
// 设置 RESX 格式多语言资源文件 如 Program.{CultureName}.resx
options.ResourceManagerStringLocalizerType = typeof(Program);
// 设置 Json 格式嵌入式资源文件
options.AdditionalAssemblies = new[] { typeof(BootstrapBlazor.Shared.App).Assembly };
// 设置 Json 物理路径文件
options.AdditionalJsonFiles = new string[]
{
@"D:\Argo\src\BootstrapBlazor\src\BootstrapBlazor.Server\Locales\zh-TW.json",
@"D:\Argo\src\BootstrapBlazor\src\BootstrapBlazor.Server\Locales\zh-CN.json"
};
});
}
Web Assembly
1. 启用 .NET 核心本地化服务
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
// 增加 BootstrapBlazor 组件
builder.Services.AddBootstrapBlazor();
builder.Services.AddSingleton<ICultureStorage, DefaultCultureStorage>();
// 增加本地化
builder.Services.Configure<BootstrapBlazorOptions>(op =>
{
op.ToastDelay = 4000;
op.SupportedCultures.AddRange(new string[] { "zh-CN", "en-US" });
});
var host = builder.Build();
await GetCultureAsync(host);
await host.RunAsync();
}
private static async Task GetCultureAsync(WebAssemblyHost host)
{
var jsRuntime = host.Services.GetRequiredService<IJSRuntime>();
var cultureName = await jsRuntime.InvokeAsync<string>("$.blazorCulture.get") ?? "zh-CN";
var culture = new CultureInfo(cultureName);
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
}
internal class DefaultCultureStorage : ICultureStorage
{
public CultureStorageMode Mode { get; set; } = CultureStorageMode.LocalStorage;
}
2. 实现 UI 本地化信息存储(例如,localStorage)
与 Server-Side 一致
更改默认语言设置
public static async Task Main(string[] args)
{
// 设置默认文化为 zh-CN
CultureInfo.CurrentCulture = new CultureInfo("zh-CN");
CultureInfo.CurrentUICulture = new CultureInfo("zh-CN");
// ...
var host = builder.Build();
await GetCultureAsync(host);
await host.RunAsync();
}