IViewLocalizer 有时在 .net core 3.1 中不起作用



>我在应用程序中配置了全球化,问题是当我调用正在进行服务调用的控制器方法时,它不起作用(实际上是返回密钥(。 当我删除服务调用并且方法保持为空时,它工作得很好。

public async Task<IActionResult> Index(int id)
{
var item = _mapper.Map<ItemViewModel>(await _itemService.GetById(id));
item.ItemImages = await _itemImageService.GetImageByItemId(id);
return View(null);
}

剃须刀页面

@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
@{
ViewData["Title"] = "Index";
}

<div class="container" style="margin:100px 0 0 0">
<h1>@Localizer["Category"]</h1>
</div>

启动.cs

services.AddLocalization(opts => opts.ResourcesPath = "Resources");
services.AddMvc()
.AddViewLocalization(
LanguageViewLocationExpanderFormat.Suffix,
opts => opts.ResourcesPath = "Resources")
.AddDataAnnotationsLocalization();

services.AddControllersWithViews();
services.AddRazorPages();

配置

var supportedCultures = new[]
{
new CultureInfo("am-AM"),
new CultureInfo("en-US"),
new CultureInfo("ru-RU")
};
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("en-US"),
SupportedCultures = supportedCultures,
SupportedUICultures = supportedCultures
});

所以我从 ASP.NET Core团队那里得到了答案。在这里分享它,以便其他遇到这篇文章的人可以找到它。

观察到的行为的原因是 .NET Core 将CultureInfo存储在 AsyncLocal 上,这会导致区域性存储在给定异步控制流的本地 - 在本例中为异步方法。

ASP.NET 团队共享的示例有助于进一步阐明这一点:

static async Task Main(string[] args)
{
await SetCultureActionFilter();
Console.WriteLine(CultureInfo.CurrentCulture);
}
static async Task SetCultureActionFilter()
{
await Task.Yield();
CultureInfo.CurrentCulture = new CultureInfo("fr-FR");
Console.WriteLine(CultureInfo.CurrentCulture);
}

上面的代码将具有以下输出:

fr-FR
en-US

溶液

不应在操作筛选器/操作执行上下文中设置区域性。 相反,应该使用已经在代码中注册的本地化中间件。如文档所示,对于生产应用,建议使用CookieRequestCultureProvider.DefaultCookieNamecookie 来指定区域性。该 Cookie 具有以下格式:c=%LANGCODE%|uic=%LANGCODE%。因此,您可以将其设置为c=am|uic=am并且应该获取与所需区域性匹配的要呈现的资源。

下面是可用于更改页面区域性的示例操作:

public IActionResult ChangeCulture(string culture)
{
Response.Cookies.Append(CookieRequestCultureProvider.DefaultCookieName, $"c={culture}|uic={culture}");
return RedirectToAction("Index");
}

然后,当用户单击相应的区域性按钮时,只需调用/[controller]/changeculture?culture=am的操作作为示例。

或者,可以通过?culture=am-AM查询字符串参数指定区域性。

希望这有帮助!

最新更新