Car*_*mas 8 c# localization blazor blazor-server-side
我需要根据每种文化的资源文件在运行时更改文化。
预期的
用户单击从当前语言切换到另一种语言的按钮。页面中的文本根据每种文化的资源文件进行刷新。
实际的
用户单击从当前语言切换到另一种语言的按钮。页面中的文本根据每种文化的资源文件进行刷新。一旦用户对任何组件(我有几个单选按钮、按钮和复选框)执行任何操作,文本就会返回到第一次编写的内容。就像 CultureInfo 根本没有改变一样。
尝试
创建一个注入到组件的 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();
}
Run Code Online (Sandbox Code Playgroud)
还在startup.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;
});
Run Code Online (Sandbox Code Playgroud)
组件注入了 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>
Run Code Online (Sandbox Code Playgroud)
然后设置事件
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();
}
Run Code Online (Sandbox Code Playgroud)
因此,现在当单击触发CambiarIdioma()的按钮时,该项目可以正常工作。但是,一旦在组件内完成任何操作(假设我检查了TablaReconocimientos组件内的某些内容或单击单选按钮),文本就会恢复为其原始字符串。
每个需要本地化文本的组件都注入了 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();
}
}
Run Code Online (Sandbox Code Playgroud)
您需要使用 Cookie 来存储所选的文化。请参阅微软文档。 https://learn.microsoft.com/en-us/aspnet/core/blazor/globalization-localization?view=aspnetcore-5.0#cookies
从文档中:
Blazor 服务器 Blazor 服务器应用程序使用本地化中间件进行本地化。中间件为从应用程序请求资源的用户选择适当的区域性。
可以使用以下方法之一设置区域性:
Cookie 提供用于选择区域性的 UI 有关更多信息和示例,请参阅 ASP.NET Core 中的全球化和本地化。
Cookie 本地化文化 cookie 可以保留用户的文化。本地化中间件在后续请求中读取 cookie 以设置用户的文化。
使用 cookie 可确保 WebSocket 连接可以正确传播区域性。如果本地化方案基于 URL 路径或查询字符串,则该方案可能无法与 WebSocket 一起使用,从而无法保留区域性。因此,建议使用本地化文化 cookie。
如果文化保留在本地化 cookie 中,则可以使用任何技术来分配文化。如果应用程序已经为服务器端 ASP.NET Core 建立了本地化方案,请继续使用应用程序现有的本地化基础结构,并在应用程序的方案中设置本地化文化 cookie。
以下示例演示如何在本地化中间件可以读取的 cookie 中设置当前区域性。在 Pages/_Host.cshtml 文件中紧邻开始标记内创建 Razor 表达式:
CSHTML
复制
@using System.Globalization
@using Microsoft.AspNetCore.Localization
...
<body>
@{
this.HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
...
</body>
Run Code Online (Sandbox Code Playgroud)
应用程序按以下事件顺序处理本地化:
浏览器向应用程序发送初始 HTTP 请求。区域性由本地化中间件分配。_Host 页面 (_Host.cshtml) 中的 Razor 表达式将区域性保留在 cookie 中作为响应的一部分。浏览器打开 WebSocket 连接以创建交互式 Blazor 服务器会话。本地化中间件读取 cookie 并分配区域性。Blazor 服务器会话以正确的区域性开始。使用 RazorPage 时,请使用 Context 属性:
剃刀
复制
@{
this.Context.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
Run Code Online (Sandbox Code Playgroud)
提供 UI 以选择区域性 要提供 UI 以允许用户选择区域性,建议使用基于重定向的方法。该过程类似于用户尝试访问安全资源时在 Web 应用程序中发生的情况。用户被重定向到登录页面,然后重定向回原始资源。
该应用程序通过重定向到控制器来保留用户选择的文化。控制器将用户选择的区域性设置到 cookie 中,并将用户重定向回原始 URI。
在服务器上建立 HTTP 端点,以在 cookie 中设置用户选择的区域性,并执行重定向回原始 URI:
C#
复制
[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);
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7730 次 |
最近记录: |