Blazor 交互式本地化(多语言)实现

本文档站点的本地化基于 AntDesign.Extensions.Localization 类库实现,主要提供可交互本地化服务,能够集成官方和第三方的本地化提供者实现在运行时无刷新切换语言。另外还实现了简单的嵌入 JSON 提供者。

安装

dotnet add package AntDesign.Extensions.Localization

使用可交互本地化组件

  • Program.cs 文件中添加以下代码:

    builder.Services.AddInteractiveStringLocalizer();
    services.AddLocalization(options =>
    {
        options.ResourcesPath = "Resources";
    });
  • 在项目的 Resources 目录下创建多语言文件,格式为 {ResourceName}.{language}.resx,例如 Index.en-US.resxIndex.zh-CN.resx

    Index.en-US.resx:

    HelloHello!
    GoodbyeGoodbye!

    Index.zh-CN.resx:

    HelloHello!
    GoodbyeGoodbye!
  • 使用时在 razor 注入 IStringLocalizer服务,例如:

    @inject IStringLocalizer<Index> localizer
    
    <p>@localizer["Hello"]</p>
    <p>@localizer["Goodbye"]</p>
  • 在 Layout.razor 订阅语言变更事件,即可切换 UI 上的语言

    @implements IDisposable
    @inject ILocalizationService LocalizationService
    
    <Button OnClick="()=>LocalizationService.SetLanguage("en-US")" >English</Button>
    <Button OnClick="()=>LocalizationService.SetLanguage("zh-CN")" >中文</Button>
    
    @code {
    
        protected override void OnInitialized()
        {
            LocalizationService.LanguageChanged += OnLanguageChanged;
        }
        private void OnLanguageChanged(object sender, CultureInfo args)
        {
            InvokeAsync(StateHasChanged);
        }
        public void Dispose()
        {
            LocalizationService.LanguageChanged -= OnLanguageChanged;
        }
    }
  • 需要使用第三方 Localization 提供者,或者其他配置,可参考 官方文档。

表单验证消息的本地化

Form 组件的默认验证器是 ObjectGraphDataAnnotationsValidator,支持 DataAnnotations 的本地化。

示例:Form 表单 - 本地化

注意:暂不支持 AntDesign locales 中的验证信息配置。

DisplayAttribute 支持本地化

组件中有部分 UI 绑定利用了实体模型或者枚举类型的 DisplayAttribute 特性用作 Label 显示,如 FormItem、EnumSelect、EnumRadioGroup、EnumCheckboxGroup 等。

public class Model
  {
      [Display(Name = nameof(Resources.App.UserName), ResourceType = typeof(Resources.App))]
      public string Username { get; set; }
  }

  public enum Province
  {
      [Display(Name = nameof(Resources.App.Shanghai), ResourceType = typeof(Resources.App))]
      Shanghai,

      Jiangsu
  }

使用简单嵌入 JSON 提供者

虽然我们推荐官方的本地化方案,但是也可以用本组件文档站点的方案,利用简单嵌入 JSON 提供者实现多语言。需要注意的是,它仅支持直接注入 IStringLocalizer,不支持其泛型,本地化文件也仅支持单一文件。

  • Program.cs 文件中添加以下代码,此方法内部已调用 AddInteractiveStringLocalizer

    builder.Services.AddSimpleEmbeddedJsonLocalization(options =>
    {
        options.ResourcesPath = "Resources";
    });
  • 在项目的 Resources 目录下创建多语言文件,格式为 {language}.json,例如 en-US.jsonzh-CN.json

    // en-US.json
    {
        "Hello": "Hello!",
        "Goodbye": "Goodbye!"
    }
    
    // zh-CN.json
    {
        "Hello": "你好!",
        "Goodbye": "再见!"
    }
  • 把JSON文件的生成操作设置为嵌入的资源

    <ItemGroup>
          <EmbeddedResource Include="Resources\*.json" />
      </ItemGroup>
  • 使用时在 razor 注入 IStringLocalizer 服务(没有泛型),例如:

    @inject IStringLocalizer localizer
    
    <p>@localizer["Hello"]</p>
    <p>@localizer["Goodbye"]</p>

实现路由上的语言标识

从本站点建立之初,就实现了路由的语言标记,有如下特点:

  1. 进入页面时可根据浏览器环境,自动在路由上添加 {locale} 参数,例如 /en-US/Index

  2. 可以根据路由上已有标识切换语言,因此要切换语言时只需跳转到对应语言的路径即可。

以下是实现方式:

  • 首先,在 Routes.razor 文件实现 Router 组件的 OnNavigateAsync 方法,调用 LocalizationService.SetLanguage 方法切换语言。

@using System.Reflection
@using System.Globalization

<ConfigProvider>
    <Router AppAssembly="typeof(App).Assembly" OnNavigateAsync="OnNavigateAsync">
        <Found Context="routeData">
            <RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)" />
            <FocusOnNavigate RouteData="routeData" Selector="h1" />
        </Found>
        <NotFound>
            <Result Status="404" />
        </NotFound>
    </Router>
    <AntContainer />
</ConfigProvider>

@inject ILocalizationService LocalizationService;
@inject NavigationManager NavigationManager;
@code{
    async Task OnNavigateAsync(NavigationContext navigationContext)
    {
        var relativeUri = navigationContext.Path;
        var currentCulture = LocalizationService.CurrentCulture;

        var segment = relativeUri.IndexOf('/') > 0 ? relativeUri.Substring(0, relativeUri.IndexOf('/')) : relativeUri;

        if (string.IsNullOrWhiteSpace(segment))
        {
            NavigationManager.NavigateTo($"{currentCulture.Name}/{relativeUri}");
            return;
        }
        else
        {
            if (segment.IsIn("zh-CN", "en-US"))
            {
                LocalizationService.SetLanguage(CultureInfo.GetCultureInfo(segment));
            }
            else if (currentCulture.Name.IsIn("zh-CN", "en-US"))
            {
                NavigationManager.NavigateTo($"{currentCulture.Name}/{relativeUri}");
            }
            else
            {
                NavigationManager.NavigateTo($"en-US/{relativeUri}");
                return;
            }
        }
    }
}
  • 最后,给页面组件统一添加 {locale} 参数,使切换后的路由匹配对应的页面。

@page "/{locale}/Index"

@inject IStringLocalizer<Index> localizer

<p>@localizer["Hello"]</p>

@code {

    [Parameter]
    public string Locale { get; set; }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值