有点困惑,这是ASP.Net Core 2.0中本地化的超级简单的hello-world示例。我的关于页面设置为呈现两个本地化字符串:
IViewLocalizer
)IStringLocalizer<HomeController>
)控制器中的代码拒绝正确获取loc字符串。这并不复杂,我错过了哪些明显的事情?
About.cshtml
@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
@{
ViewData["Title"] = "About";
}
<h2>@ViewData["Title"]</h2>
<h3>@ViewData["Message"]</h3>
<p>@Localizer["Use this area to provide additional information."]</p>
^注意两个字符串:“Message”将使用IStringLocalizer
从代码进行本地化(请参阅下面的HomeController),@ Local将使用IViewLocalizer
类。
HomeController.cs
public class HomeController : Controller
{
private readonly IStringLocalizer _localizer;
public HomeController(IStringLocalizer<HomeController> localizer)
{
_localizer = localizer;
}
public IActionResult Index()
{
return View();
}
public IActionResult About()
{
ViewData["Message"] = _localizer["Your application description page."];
return View();
}
}
Startup.cs (相关部分)
public void ConfigureServices(IServiceCollection services)
{
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("fr-CH"),
};
options.DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var locOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(locOptions.Value);
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
资源:
Views.Home.About.fr-CH.resx
^中包含两个值:
我的结果:
本地主机:56073 /首页/
^这会在en-US中呈现预期的字符串(默认找不到任何内容,使用实际硬编码的字符串)
本地主机:56073 /首页/关于培养= FR-CH
^这只会呈现第二个字符串:“使用此区域... fr-CH成功!”, 显然意味着所有已连接的代码正在运行 并按预期找到fr-CH.resx。
但是,第一个字符串(在代码中设置为ViewData["Message"]
)不会得到fr-CH版本!这就像IStringLocalizer<HomeController>
失败,意识到指定了lang,或者找不到明显可用的fr-CH.resx。
为什么???
同样顺便说一句,我也试过使用ShareResource示例(参见下面的链接),并将工厂传递给HomeController ctor IStringLocalizerFactory factory
,也没有爱,仍然没有获得fr-CH资源。叹息。
其他说明:
将此作为我的主要参考: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization
使用VS 2017,最新更新,使用ASP.Net Core 2.0
答案 0 :(得分:2)
您在控制器中使用IStringLocalizer<HomeController>
作为本地化程序来查找本地化字符串。本地化程序将在Resources
文件夹中查找YouControllerNameSpace.HomeController
资源文件,因为它找不到它,它将返回您传递给本地化程序的原始密钥。
要解决此问题,您可以使用以下任一选项:
IStringLocalizer<T>
IStringLocalizerFactory
有关资源文件名的更多信息,请查看文档中的Resource file naming部分。
使用此选项,您应该拥有一个与T的全名同名的资源文件,在您的情况下,控制器代码应该与它相同:
IStringLocalizer _localizer;
public HomeController(IStringLocalizer<HomeController> localizer)
{
_localizer = localizer;
}
对于资源文件:
YouControllerNameSpace.HomeController
资源文件。 (YouControllerNameSpace
只是一个占位符,使用您的控制器命名空间。)使用此选项,您可以将任何文件用作资源文件。例如,如果要从Views.Home.About
资源文件中读取资源,则应将控制器代码更改为:
IStringLocalizer _localizer;
public HomeController(IStringLocalizerFactory factory)
{
_localizer = factory.Create("Views.Home.About",
System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
}
对于资源文件:
Views.Home.About
资源文件。答案 1 :(得分:0)
尝试this answer中tmg描述的技术。
具体来说,尝试添加行
options.RequestCultureProviders = new List<IRequestCultureProvider>
{
new QueryStringRequestCultureProvider(),
new CookieRequestCultureProvider()
};
到您的ConfigureServices()函数
答案 2 :(得分:0)
问题是ASP .NET Core使用IStringLocalizer为本地化创建了错误的RESX名称空间。如果您在代码中
services.AddLocalization(options => options.ResourcesPath = "Resources");
然后,注入的服务IStringLocalizer的实例在名称空间中具有两次“ Resources”,名称空间看起来是“ Resources.Resources”。这是找不到RESX的根本原因。