为你的Blazor程序加入本地化多语言功能

本地化

本地化是为给定语言和地区定制应用程序的过程. BootstrapBlazor 组件允许您将其 UI 元素转换为所需的语言。这包括按钮、过滤器操作符属性等文本。组件内部默认使用当前请求 UI 文化语言,本文将向您展示如何在应用程序中使用此功能:

BootstrapBlazor 组件库

简介
BootstrapBlazor 是一套基于 Bootstrap 和 Blazor 的企业级组件库,可以认为是 Bootstrap 项目的 Blazor 版实现。

小提示

阅读以下知识点前请先查看 微软官方文档
由于 wasm 模式无法获取系统语言文化信息,默认文化信息为 en
组件内置本地化资源文件为 en zh 由网友提供的其他本地化资源文件 de es pt zh-TW 放置在项目文件夹 localization 内,可自行下载通过注入服务引入到项目中

本地化在组件中的工作原理

BootstrapBlazor 组件额外支持使用 Json 类型的键值信息作为资源文件,将其解析为 UI 中呈现的字符串。BootstrapBlazor 包自带以下资源文件。

  • 中文(zh)
  • 英语(en)

额外本地化语言 json 文件

  • 德语(de)
  • 葡萄牙语(pu)
  • 西班牙语(es)
  • 中國台灣(zh-TW)

组件库本地化详细资讯链接

https://www.blazor.zone/localization

开始撸码

跟往常一样,CV福音

源码在此.

Bootstrap Blazor App 模板, 快速搭建项目

  1. 新建bb模板工程
dotnet new install Bootstrap.Blazor.Templates::9.0.4 dotnet new bbapp 
  1. 加入语言选择功能

右键新建blazor组件 CultureChooser.razor

新建组件步骤参考往期文章

加入如下代码

@inherits BootstrapComponentBase @namespace BootstrapBlazor.Server.Components.Components  <div @attributes="@AdditionalAttributes" class="@ClassString">     <span>@Label</span>     <Select Value="@SelectedCulture" OnSelectedItemChanged="@SetCulture">         <Options>             @foreach (var kv in BootstrapOptions.CurrentValue.GetSupportedCultures())             {                 <SelectOption Text="@GetDisplayName(kv)" Value="@kv.Name" />             }         </Options>     </Select> </div>  

为你的Blazor程序加入本地化多语言功能

新建代码后置文件 CultureChooser.razor.cs

新建代码后置文件步骤参考往期文章

using BootstrapBlazor.Components; using Microsoft.AspNetCore.Components; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Options; using Microsoft.JSInterop; using System.Diagnostics.CodeAnalysis; using System.Globalization;  namespace BootstrapBlazor.Server.Components.Components;  /// <summary> ///  /// </summary> public partial class CultureChooser {     [Inject]     [NotNull]     private IOptionsMonitor<BootstrapBlazorOptions>? BootstrapOptions { get; set; }      [Inject]     [NotNull]     private IStringLocalizer<CultureChooser>? Localizer { get; set; }      [Inject]     [NotNull]     private NavigationManager? NavigationManager { get; set; }      private string? ClassString => CssBuilder.Default("culture-selector")         .AddClassFromAttributes(AdditionalAttributes)         .Build();      private string SelectedCulture { get; set; } = CultureInfo.CurrentCulture.Name;      [NotNull]     private string? Label { get; set; }      /// <summary>     /// OnInitialized 方法     /// </summary>     protected override void OnInitialized()     {         base.OnInitialized();          Label ??= Localizer[nameof(Label)];     }      private async Task SetCulture(SelectedItem item)     {         if (RendererInfo.Name == "Server")         {             // 使用 api 方式 适用于 Server-Side 模式             if (SelectedCulture != item.Value)             {                 var culture = item.Value;                 var uri = new Uri(NavigationManager.Uri).GetComponents(UriComponents.PathAndQuery, UriFormat.SafeUnescaped);                 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         {             if (SelectedCulture != item.Value)             {                 var culture = item.Value;                 await JSRuntime.InvokeVoidAsync("bbCulture.set", culture);                  NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true);             }         }     }      private string GetDisplayName(CultureInfo culture)     {         string? ret;         if (RendererInfo.Name == "Server")         {             ret = culture.NativeName;         }         else         {             ret = culture.Name switch             {                 "zh-CN" => "中文(中国)",                 "en-US" => "English (United States)",                 _ => ""             };         }         return ret;     } } 

为你的Blazor程序加入本地化多语言功能

  1. 布局文件添加语言选择

编辑 MainLayout.razor 在<Widget></Widget>后面加入一行

<BootstrapBlazor.Server.Components.Components.CultureChooser /> 

为你的Blazor程序加入本地化多语言功能

  1. 增加多语言支持配置信息,启用本地化

编辑 Program.cs 在builder.Services.AddBootstrapBlazor();后加入这些代码

// 增加多语言支持配置信息 builder.Services.AddRequestLocalization<IOptionsMonitor<BootstrapBlazorOptions>>((localizerOption, blazorOption) => {     blazorOption.OnChange(Invoke);     Invoke(blazorOption.CurrentValue);     return;      void Invoke(BootstrapBlazorOptions option)     {         var supportedCultures = option.GetSupportedCultures();         localizerOption.SupportedCultures = supportedCultures;         localizerOption.SupportedUICultures = supportedCultures;     } });  builder.Services.AddControllers(); 

然后在var app = builder.Build();后加入这行代码

// 启用本地化 var option = app.Services.GetService<IOptions<RequestLocalizationOptions>>(); if (option != null) {     app.UseRequestLocalization(option.Value); } 

最后在app.MapStaticAssets();后加入这行代码

app.MapDefaultControllerRoute(); 
  1. 添加控制器

新建文件夹Controllers, 新建文件 CultureController.cs

using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Mvc; using RouteAttribute = Microsoft.AspNetCore.Mvc.RouteAttribute;  namespace BootstrapBlazor.Controllers;  /// <summary> /// 文化 Controller /// </summary> [Route("[controller]/[action]")] public class CultureController : Controller {     /// <summary>     /// 设置文化方法     /// </summary>     /// <param name="culture"></param>     /// <param name="redirectUri"></param>     /// <returns></returns>     public IActionResult SetCulture(string culture, string redirectUri)     {         if (string.IsNullOrEmpty(culture))         {             HttpContext.Response.Cookies.Delete(CookieRequestCultureProvider.DefaultCookieName);         }         else         {             HttpContext.Response.Cookies.Append(                 CookieRequestCultureProvider.DefaultCookieName,                 CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture, culture)), new CookieOptions()                 {                     Expires = DateTimeOffset.Now.AddYears(1)                 });         }          return LocalRedirect(redirectUri);     }      /// <summary>     /// 重置文化方法     /// </summary>     /// <param name="redirectUri"></param>     /// <returns></returns>     public IActionResult ResetCulture(string redirectUri)     {         HttpContext.Response.Cookies.Delete(CookieRequestCultureProvider.DefaultCookieName);          return LocalRedirect(redirectUri);     } }  
  1. 运行工程

为你的Blazor程序加入本地化多语言功能

因为模板工程已经带了部分多语言配置, 我们点击Table或者花名册页面就可以看到效果

为你的Blazor程序加入本地化多语言功能

为你的Blazor程序加入本地化多语言功能

实践

通过主页面改变欢迎词来练习

为你的Blazor程序加入本地化多语言功能

代码<SurveyPrompt Title="How is Blazor working for you?" />改为

<SurveyPrompt Title="@Localizer["Wellcome"]" /> <SurveyPrompt Title="@Localizer["How is Blazor working for you?"]" />  @code{     [Inject]     [NotNull]     private IStringLocalizer<Index>? Localizer { get; set; }  } 

在这里我们写了两行@Localizer,先买个关子,运行时候看看是什么效果.

为你的Blazor程序加入本地化多语言功能

添加本地化资源

分别在Locales/zh.jsonLocales/en.json添加对应的文字

  "BootstrapBlazorApp.Server.Components.Pages.Index": {     "Wellcome": "Blazor 对你有什么帮助?"   } 
  "BootstrapBlazorApp.Server.Components.Pages.Index": {     "Wellcome": "How is Blazor working for you?"   } 

为你的Blazor程序加入本地化多语言功能

为你的Blazor程序加入本地化多语言功能

运行工程
为你的Blazor程序加入本地化多语言功能

为你的Blazor程序加入本地化多语言功能

现在可以看到效果了, 找到资源的已经正确显示对应文本, 未找到资源的,会回落显示为key.

TIPS

  1. 格式化

资源文件

"Foo.Address2": "地球、中国、上海市普陀区金沙江路 {0} 弄 这里是超长单元格示例" 

c#

var i=1274;  localizer["Foo.Address", i] 

效果

上海市普陀区金沙江路 1274 弄 
  1. 特性相关,例如必填项

字段定义

    [Required(ErrorMessage = "{0}不能为空")]     [AutoGenerateColumn(Order = 10, Filterable = true, Searchable = true)]     [Display(Name = "姓名")]     public string? Name { get; set; } 

资源文件

"Name.Required": "{0}是必填项"  "Name.Required": "{0} is required." 

效果

为你的Blazor程序加入本地化多语言功能

为你的Blazor程序加入本地化多语言功能

组件库本地化详细资讯链接

https://www.blazor.zone/localization

发表评论

相关文章