dap*_*pug 3 c# localization asp.net-core asp.net-core-localization asp.net-core-2.0
这里有点困惑,ASP.Net Core 2.0 中本地化的超级简单 hello-world 示例。我的关于页面设置为呈现两个本地化字符串:
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>
Run Code Online (Sandbox Code Playgroud)
^ 请注意这两个字符串:“Message”将使用代码本地化IStringLocalizer(请参阅下面的 HomeController),@Localizer 将使用IViewLocalizer该类。
家庭控制器.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();
}
}
Run Code Online (Sandbox Code Playgroud)
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?}");
});
}
Run Code Online (Sandbox Code Playgroud)
资源:
Views.Home.About.fr-CH.resx
^ 有两个值:
我的结果:
本地主机:56073/首页/关于
^ 这会在 en-US 中按预期呈现字符串(默认找不到任何内容,使用实际硬编码的字符串)
本地主机:56073/家/关于?culture=fr-CH
^ 这仅呈现第二个字符串:“使用此区域... fr-CH 成功!”,这显然意味着连接的所有代码都在工作并按预期找到 fr-CH.resx。
但是,第一个字符串(在代码中设置为ViewData["Message"])没有得到 fr-CH 版本!这就像IStringLocalizer<HomeController> 没有意识到指定了一个 lang,或者没有找到明显可用的 fr-CH.resx。
为什么???
另外顺便说一句,我也尝试使用 ShareResource 示例(参见下面的链接),并将工厂传递给 HomeController ctor as IStringLocalizerFactory factory,同样没有爱,仍然没有获得 fr-CH 资源。叹。
其他注意事项:
将此作为我的主要参考:https : //docs.microsoft.com/en-us/aspnet/core/fundamentals/localization
使用 VS 2017,最新更新,ASP.Net Core 2.0
Ond*_*nek 12
问题在于 ASP .NET Core 使用 IStringLocalizer 创建了错误的 RESX 命名空间以进行本地化。如果你的代码中有
services.AddLocalization(options => options.ResourcesPath = "Resources");
Run Code Online (Sandbox Code Playgroud)
那么注入的服务 IStringLocalizer 的实例在命名空间中有两次“Resources”,命名空间看起来为“Resources.Resources”。这就是RESX找不到的根本原因。
您IStringLocalizer<HomeController>在控制器中用作定位器来查找本地化字符串。本地化程序将在Resources文件夹中查找YouControllerNameSpace.HomeController资源文件,由于找不到它,它将返回您传递给本地化程序的原始密钥。
要解决此问题,您可以使用以下任一选项:
IStringLocalizer<T>IStringLocalizerFactory有关资源文件名的更多信息,请查看文档中的资源文件命名部分。
使用此选项,您应该有一个与 T 的全名同名的资源文件,在您的情况下,控制器代码应该与它相同:
IStringLocalizer _localizer;
public HomeController(IStringLocalizer<HomeController> localizer)
{
_localizer = localizer;
}
Run Code Online (Sandbox Code Playgroud)
对于资源文件:
YouControllerNameSpace.HomeController资源文件。(YouControllerNameSpace只是一个占位符,使用您的控制器命名空间。)使用此选项,您可以将任何文件用作资源文件。例如,如果您想从Views.Home.About资源文件中读取资源,您应该将控制器代码更改为:
IStringLocalizer _localizer;
public HomeController(IStringLocalizerFactory factory)
{
_localizer = factory.Create("Views.Home.About",
System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
}
Run Code Online (Sandbox Code Playgroud)
对于资源文件:
Views.Home.About资源文件。| 归档时间: |
|
| 查看次数: |
21697 次 |
| 最近记录: |