Blazor Webassembly本地化的实现

       若是要支持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>

  

 至此,涉及本地化的主要步骤和关键点就完成了,你就能够测试您的代码了。

相关文章
相关标签/搜索