在控制器上进行设置时,我在设置View中的本地化时遇到问题。以下是我遵循的步骤。
public void ConfigureServices(IServiceCollection services)
{
services.AddLocalization(option=>option.ResourcesPath="services.AddLocalization(options => options.ResourcesPath = "StringResources");");
// Add application services.
services.AddTransient<IEmailSender, EmailSender>();
services.AddMvc()
.AddViewLocalization(Microsoft.AspNetCore.Mvc.Razor.LanguageViewLocationExpanderFormat.Suffix);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var supportedCultures = new[]
{
new CultureInfo("nb-NO"),
new CultureInfo("en-US"),
new CultureInfo("zh-CN"),
};
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("en-US"),
// Formatting numbers, dates, etc.
SupportedCultures = supportedCultures,
// UI strings that we have localized.
SupportedUICultures = supportedCultures
});
app.UseStaticFiles();
}
并创建 StringResources
文件夹,添加了一个名为 SharedResources.en-us.resx文件的文件。
按如下方式创建控制器
public class AccountController : Controller
{
private IStringLocalizer<SharedResources> _sharedLocalizer;
public AccountController(
IStringLocalizer<SharedResources> sharedLocalizer
)
{
_sharedLocalizer = sharedLocalizer;
}
}
以上在控制器中工作但在视图中不起作用。我的HTML如下,
@inject IHtmlLocalizer<SharedResources> SharedLocalizer;
<h1>@SharedLocalizer["LogInTo"]<br>
现在视图上的输出是 LogInTo ,而我期待它 Logg inn
答案 0 :(得分:2)
每次聊天我们都能弄清楚这个问题的原因是什么。
基本上,关于这一点的奇怪部分是IStringLocalizer
似乎有效,而IHtmlLocalizer
则没有。这通常不应该是一个问题,因为IHtmlLocalizer
实际上只是字符串本地化程序周围的一个非常薄的层,它添加了一些HTML编码,使其在Razor视图中很有用。
所以我们看到的另一个角度是控制器中是否还有其他代码会影响本地化程序的工作方式。以前的测试代码明确设置了当前的线程区域设置,因此我们必须确保仍然存在 问题,并且控制器和视图中的本地化程序都在同一个区域内执行上下文。
这给我们留下了本地化器。通用本地化程序的工作方式是它们使用泛型类型参数进行命名以解析资源。事实上,一个本地化程序能够从资源文件生成字符串,而另一个本地化程序无法解析任何字符串,这两个本地化程序显然使用了不同的资源文件。
确实存在问题:在视图中注入的IHtmlLocalizer<SharedResources>
引用了与注入视图的SharedResources
不同的IStringLocalizer<SharedResources>
类型。
除非视图中有明确的@using
指令,否则Razor引擎将遵守_ViewImports.cshtml
文件中的using指令。该文件中的@using
可能会访问{em} 名称空间中的SharedResources
类型,而不是预期的类型。所以Razor没有抱怨,因为它可以找到一个具有该名称的类型,但它最终变成了另一个。
就像在普通的C#代码中一样,您始终可以使用完整命名空间指定类型。当不同名称空间中存在具有相同名称的类型时,这可以避免冲突。因此,避免此问题的最安全方法是更改@inject
指令以使用SharedResources
类型的完整命名空间:
@inject IHtmlLocalizer<Utilities.Resources.SharedResources> SharedLocalizer