Blazor - 在运行时更改 UI CultureInfo

2024-02-22

我需要根据每种文化的资源文件在运行时更改文化。

Expected

用户单击从当前语言切换到另一种语言的按钮。页面中的文本根据每种文化的资源文件进行刷新。

Actual

用户单击从当前语言切换到另一种语言的按钮。页面中的文本根据每种文化的资源文件进行刷新。一旦用户对任何组件(我有几个单选按钮、按钮和复选框)执行任何操作,文本就会返回到第一次编写的内容。就像 CultureInfo 根本没有改变一样。

Tries

创建一个注入到组件的 AppState 类

    public class AppState
{
    public CultureInfo currentCulture { get; private set; } = CultureInfo.CurrentCulture;
    public event Action OnChange;
    public void ChangeCulture(CultureInfo newCulture)
    {
        currentCulture = newCulture;
        System.Threading.Thread.CurrentThread.CurrentCulture.ClearCachedData();
        System.Threading.Thread.CurrentThread.CurrentUICulture.ClearCachedData();
        System.Threading.Thread.CurrentThread.CurrentCulture = newCulture;
        System.Threading.Thread.CurrentThread.CurrentUICulture = newCulture;
        NotifyStateChanged();
    }

    public CultureInfo getCurrentCulture()
    {
        if (currentCulture == null)
        {
            ChangeCulture(CultureInfo.CurrentCulture);
        }
        return currentCulture;

    }

    private void NotifyStateChanged() => OnChange?.Invoke();
}

为项目添加了本地化启动.cs和 AppState instante 也是如此

        services.AddScoped<AppState>();
        services.AddMvc().AddMvcLocalization();
        services.AddLocalization();
        var supportedCultures = new List<CultureInfo> { new CultureInfo("en-US"), new CultureInfo("es-ES") };
        services.Configure<RequestLocalizationOptions>(options =>
        {
            options.DefaultRequestCulture = new RequestCulture("es-ES");
            options.SupportedUICultures = supportedCultures;
            options.SupportedCultures = supportedCultures;
        });

组件注入了 AppState 以及 IStringLocalizer 对象,以从资源文件中获取字符串。

@inject AppState state
@inject IStringLocalizer<Index> _localizer

@implements IDisposable

<div class="uk-container" id="data_container">
    <button @onclick="e => CambiarIdioma()">Holadenuevo</button>

    <TablaReconocimientos @ref="tablaReconocimientos" searchText="@navigatableSearchInput"></TablaReconocimientos>
</div>

然后设置事件

    protected override void OnInitialized()
    {
        _lematizador = new LematizadorService();

        state.OnChange += OnCultureChange;
    }

    public void Dispose()
    {
        state.OnChange -= OnCultureChange;
    }
    private void CambiarIdioma()
    {
        if (state.getCurrentCulture().Equals(new CultureInfo("es-ES")))
        {
            state.ChangeCulture(new CultureInfo("en-US"));
        }
        else
        {
            state.ChangeCulture(new CultureInfo("es-ES"));
        }
    }

    private void OnCultureChange()
    {
        CultureInfo.CurrentCulture = state.currentCulture;
        CultureInfo.CurrentUICulture = state.currentCulture;

        StateHasChanged();
    }

所以现在当点击触发的按钮时坎比亚尔习语()该项目运行良好。但是一旦组件内部完成任何操作(假设我检查了组件内部的某些内容)塔布拉歌谣组件或我单击单选按钮)文本将恢复为其原始字符串。

每个需要本地化文本的组件都注入了 AppState 并实现了以下功能:

@inject AppState state
@inject IStringLocalizer<TablaModos> _localizer

@implements IDisposable


@*Component stuff*@

@functions{
    protected override void OnInitialized()
    {
        state.OnChange += OnCultureChange;
    }

    public void Dispose()
    {
        state.OnChange -= OnCultureChange;
    }

    private void OnCultureChange()
    {
        CultureInfo.CurrentCulture = state.currentCulture;
        CultureInfo.CurrentUICulture = state.currentCulture;

        StateHasChanged();
    }

}

Image as exmaple of whats happening at the moment: enter image description here


您需要使用 Cookie 来存储所选的文化。请参阅微软文档。https://learn.microsoft.com/en-us/aspnet/core/blazor/globalization-localization?view=aspnetcore-5.0#cookies https://learn.microsoft.com/en-us/aspnet/core/blazor/globalization-localization?view=aspnetcore-5.0#cookies

从文档中:

Blazor服务器 Blazor 服务器应用程序使用本地化中间件进行本地化。中间件为从应用程序请求资源的用户选择适当的区域性。

可以使用以下方法之一设置区域性:

饼干 提供UI来选择文化 有关更多信息和示例,请参阅 ASP.NET Core 中的全球化和本地化。

饼干 本地化文化 cookie 可以保留用户的文化。本地化中间件在后续请求中读取 cookie 以设置用户的文化。

使用 cookie 可确保 WebSocket 连接可以正确传播区域性。如果本地化方案基于 URL 路径或查询字符串,则该方案可能无法与 WebSocket 一起使用,从而无法保留区域性。因此,建议使用本地化文化 cookie。

如果文化保留在本地化 cookie 中,则可以使用任何技术来分配文化。如果应用程序已经为服务器端 ASP.NET Core 建立了本地化方案,请继续使用应用程序现有的本地化基础结构,并在应用程序的方案中设置本地化文化 cookie。

以下示例演示如何在本地化中间件可以读取的 cookie 中设置当前区域性。在 Pages/_Host.cshtml 文件中紧邻开始标记内创建 Razor 表达式:

CSHTML

Copy

@using System.Globalization
@using Microsoft.AspNetCore.Localization

...

<body>
    @{
        this.HttpContext.Response.Cookies.Append(
            CookieRequestCultureProvider.DefaultCookieName,
            CookieRequestCultureProvider.MakeCookieValue(
                new RequestCulture(
                    CultureInfo.CurrentCulture,
                    CultureInfo.CurrentUICulture)));
    }

    ...
</body>

应用程序按以下事件顺序处理本地化:

浏览器向应用程序发送初始 HTTP 请求。 区域性由本地化中间件分配。 _Host 页面 (_Host.cshtml) 中的 Razor 表达式将区域性保留在 cookie 中作为响应的一部分。 浏览器打开 WebSocket 连接以创建交互式 Blazor 服务器会话。 本地化中间件读取 cookie 并分配区域性。 Blazor 服务器会话以正确的区域性开始。 使用 RazorPage 时,请使用 Context 属性:

razor

Copy

@{
    this.Context.Response.Cookies.Append(
        CookieRequestCultureProvider.DefaultCookieName,
        CookieRequestCultureProvider.MakeCookieValue(
            new RequestCulture(
                CultureInfo.CurrentCulture,
                CultureInfo.CurrentUICulture)));
}

提供UI来选择文化 为了提供 UI 来允许用户选择区域性,建议使用基于重定向的方法。该过程类似于用户尝试访问安全资源时 Web 应用程序中发生的情况。用户被重定向到登录页面,然后重定向回原始资源。

该应用程序通过重定向到控制器来保留用户选择的文化。控制器将用户选择的区域性设置到 cookie 中,并将用户重定向回原始 URI。

在服务器上建立 HTTP 端点,以在 cookie 中设置用户选择的区域性,并执行重定向回原始 URI:

C#

Copy

[Route("[controller]/[action]")]
public class CultureController : Controller
{
    public IActionResult SetCulture(string culture, string redirectUri)
    {
        if (culture != null)
        {
            HttpContext.Response.Cookies.Append(
                CookieRequestCultureProvider.DefaultCookieName,
                CookieRequestCultureProvider.MakeCookieValue(
                    new RequestCulture(culture)));
        }

        return LocalRedirect(redirectUri);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Blazor - 在运行时更改 UI CultureInfo 的相关文章

随机推荐

  • 将 AutoHideSplashScreen 选项与 PhoneGap / Cordova 应用程序结合使用

    我已经尝试过plugin https github com phonegap phonegap plugins tree master iPhone SplashScreen但我似乎不知道如何让它与科尔多瓦一起工作 没有插件navigato
  • 将数据库中的多个纬度/经度点加载到谷歌地图标记中的好方法?

    我有一个包含多个地址的表 包括它们的纬度 经度坐标 并且我想使用 asp net webforms 和 Google Maps Javascript API V3 将其中许多标记一次性放置到 google 地图上 这些教程展示了如何添加一个
  • PySpark:如何重新采样频率

    想象一个由变量的值观察组成的 Spark Dataframe 每个观察都有一个特定的时间戳 并且不同变量之间的这些时间戳不相同 这是因为时间戳是在变量值更改并记录时生成的 Variable Time Value 852 YF 007 201
  • 在 Phonegap 2.5 中加载外部 URL 时出错

    我从头开始创建了一个新的 Phonegap 2 5 项目 我一直在尝试在其中加载外部 URL 但在加载实际 URL 之前 我总是在启动时弹出输入框 我首先看到一个带有网站 URL 的弹出窗口 然后在输入框中显示 DeviceInfo Dev
  • 通过多点连接发送和接收邀请

    我知道这个问题之前已经被问过 但我只是想知道为什么它在我的特定情况下不起作用 我正在尝试从一个视图控制器的多点连接发送邀请 并在另一个视图控制器上接收它 我的发送代码是 self invitePeer selectedPeerID toSe
  • Chrome 中的 cors 预检选项请求速度缓慢 [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我正在努力解决一个奇怪的问题 这只发生在 Chrome 中 我的 Angular SPA 与不同子域 api domai
  • html 堆栈顺序

    考虑以下代码
  • 将字符串转换为日期 [包含年份和季度]

    我有一个 pandas 数据框 其中一列包含年份和季度的字符串 格式如下 2015Q1 我的问题 如何将其转换为两个日期时间列 一个代表年份 一个代表季度 您可以使用split http pandas pydata org pandas d
  • EF Core 中修改的实体所拥有的类型属性不持久

    我正在尝试在 EF Core 中实现一些在 EF 6 中对我来说非常有效的目标 我正在序列化 a 的内容List
  • 不使用密钥库的客户端证书

    我试图弄清楚是否有任何方法可以让 NET 客户端使用客户端证书而不以任何方式涉及 Windows 密钥库 我有一个这样的代码片段 test1 Service s new test1 Service X509Certificate c X50
  • JFreeChart日期轴格式化问题

    我有一个时间序列图表 我的 X 轴是日期 Y 轴只是数字 我正在尝试格式化 x 轴上的日期 但是我不断收到异常 我的代码如下 TimeSeries trueSeries new TimeSeries True Data TimeSeries
  • firebase 正在从数据库中检索已删除的数据

    我正在使用 firebase 实时数据库 它对于我的应用程序的某些部分运行良好 我正在阅读 youtube 上的一个教程 该教程用用户填充 collectionView 它使用 NSDictionary 获取照片 URL 和用户名 并将它们
  • Spring Boot + Angular 文件上传无法上传同一文件两次

    chrome 网络下出错 timeStamp status 400 error Bad Request message Required request part file is not present path url as hosted
  • malloc 和 realloc 之间的区别?

    假设我有两个用于创建 10 个元素的整数数组的代码示例 int pi int 0 realloc pi 10 另一种是正常写法 即 int pi pi malloc 10 sizeof int 现在 我的问题是 第一种赋值是合法的 但没有被
  • 点间最短距离算法

    给定平面上的一组点 找到由这些点中的任意两个点形成的最短线段 我怎样才能做到这一点 最简单的方法显然是计算每个距离 但我需要另一种算法来比较 http en wikipedia org wiki Closest pair of points
  • Nginx 身份验证(本地网络除外)

    来自 apache2 的一个功能我无法实现 仅要求对外部访问进行身份验证 但对本地网络上的用户进行免费访问 有什么想法可以轻松处理这种情况吗 任何帮助 将不胜感激 我已经删除了之前的答案 并想建议我在下面提供的解决方案 我做了一些搜索 找到
  • .net标准类库-不支持分布式事务错误

    我在 net标准类库项目中开发了一个日志服务 它可以完美工作 无需系统 事务 事务范围类 当我向进程添加事务时 记录器插入方法引发异常 该平台不支持分布式事务 当我使用 System Transaction 将代码添加到核心控制台应用程序时
  • 我应该如何在KAA中实现Rest API

    我使用 Kaa 沙箱发送通知 我必须在窗口终端上运行这些代码 curl v S u devuser devuser123 F notification applicationId 3 schemaId 4 topicId 1 type US
  • Python 全局变量的疯狂

    您有三个文件 main py second py 和 common py 通用 py usr bin python GLOBAL ONE Frank main py usr bin python from common import fro
  • Blazor - 在运行时更改 UI CultureInfo

    我需要根据每种文化的资源文件在运行时更改文化 Expected 用户单击从当前语言切换到另一种语言的按钮 页面中的文本根据每种文化的资源文件进行刷新 Actual 用户单击从当前语言切换到另一种语言的按钮 页面中的文本根据每种文化的资源文件