这里有点困惑,ASP.Net Core 2.0 中的超级简单的 hello-world 本地化示例。我的 About 页面设置为呈现两个本地化字符串:
IViewLocalizer
)IStringLocalizer<HomeController>
)控制器中的代码拒绝正确获取 loc 字符串。这并不复杂,我错过了哪些明显的事情?
关于.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),@Localizer 将使用
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/首页/关于?culture=fr-CH
^ 这仅呈现第二个字符串:“使用此区域... fr-CH 成功!”,这
清楚地意味着所有连接的代码都在工作 并按预期找到 fr-CH.resx。
但是,第一个字符串(在代码中设置为ViewData["Message"]
)没有获得 fr-CH 版本! 这就像
IStringLocalizer<HomeController>
failed 无法意识到指定了 lang,或者无法找到明显可用的 fr-CH.resx。 为什么???
顺便说一句,我也尝试使用 ShareResource 示例(请参阅下面的链接),并将工厂作为
IStringLocalizerFactory factory
传递给 HomeController ctor,同样没有爱,仍然没有获得 fr-CH 资源。 叹息。
其他注意事项:
以此作为我的主要参考:https://learn.microsoft.com/en-us/aspnet/core/fundamentals/localization
使用 VS 2017,最新更新,带有 ASP.Net Core 2.0
IStringLocalizer<HomeController>
作为控制器中的本地化器来查找本地化字符串。本地化程序将在
Resources
文件夹中查找
YouControllerNameSpace.HomeController
资源文件,由于找不到它,它将返回您传递给本地化程序的原始密钥。要解决该问题,您可以使用以下任一选项:
IStringLocalizer<T>
IStringLocalizerFactory
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
资源文件。
services.AddLocalization(options => options.ResourcesPath = "Resources");
然后注入的服务 IStringLocalizer 的实例在命名空间中有两次“Resources”,命名空间看起来为“Resources.Resources”。这就是RESX找不到的根本原因。
这个答案中描述的技术。
具体来说,尝试添加行
options.RequestCultureProviders = new List<IRequestCultureProvider>
{
new QueryStringRequestCultureProvider(),
new CookieRequestCultureProvider()
};
到您的ConfigureServices()函数
builder.Services.AddLocalization(options => options.ResourcesPath = "");