Blazor Webassembly本地化的实现

       如果要支持Blazor WebAssembly的本地化,应该如何实现呢?下面,我们就按照本地化问题操作中所涉及的所有主要问题以提问的方式进行说明。

1.本地化的核心原理是什么?

        答:就是显式地在Program.Main方法中设置 CultureInfo.DefaultThreadCurrentCulture和CultureInfo.DefaultThreadCurrentUICulture这两个属性。

2. 用户选择的本地化语言设置的值存放在哪里?

       有三种主要方式,第一种是存放在本地,这种优点是不涉及与服务器的网络交互,能节省一点的服务器端和网络的资源消耗,缺点是,换了客户端就要重新设置。

       第二种是存放在服务器端。这种方式优点是语言本地化设置不随着客户端的变更而变更,客户体验好,缺点就是与服务器有资源消化,在服务端不但要写Api接口,还要存储,还要考虑负载等一系列问题。

       第三种,就是将前面两种方式都结合起来,服务端和客户端都存储,如果换了客户端,客户端没有存储,就去服务端查找相应设置。客户端有,就不去查询服务器设置。这种方式结合了前面两种的优点,算是比较完美的方案。

       因为第一种方式的影响甚微,相对一直使用一种客户端的用户来说,用户换客户端的机会相对较少。通常对于用户来说,也是可以接受的,我在这里采取第一种方式首先予以说明。

3. 那么我们要将本地化设置要存放在本地浏览器的什么地方,如何实现呢?

        答案是localStorage,我们只需要在wwwroot/index.html文件中加入一段js代码,就可以搞定这一步。

    

4. 如何将第三个问题存放的设置取出来,赋给第一步说到的两个属性,以便本地化起作用?

       通过在Program.Main方法中,可以通过C#与js的交互来获取到相应设置。只要在host.RunAsync()之前调用下面定义的这个方法就完成了相关操作:

            static async Task GetCulture(WebAssemblyHost host)
            {
                var jsInterop = host.Services.GetRequiredService();
                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中的