ASP.NET Core 3 Localization 仅显示按键
ASP.NET Core 3 Localization is only displaying keys
我在让文本本地化在 ASP.NET Core 3 中工作时遇到了一些问题。或者更确切地说,它以前是工作的,但由于一次事故(没有隐藏更改并意外删除了其中的一些)它不再做。我确定我遗漏了一些基本的东西,但我可以终生解决。
我已经准备好以下代码块:
Startup.cs:
private static readonly List<CultureInfo> SupportedCultures = new List<CultureInfo>
{
new CultureInfo("en"),
new CultureInfo("fr")
};
// ...
services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix, opts => { opts.ResourcesPath = "Resources"; })
.AddDataAnnotationsLocalization(options =>
{
options.DataAnnotationLocalizerProvider = (type, factory) =>
factory.Create(typeof(Language));
})
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
});
services.AddLocalization(o =>
{
o.ResourcesPath = "Resources";
});
services.Configure<RequestLocalizationOptions>(options =>
{
options.DefaultRequestCulture = new RequestCulture("en", "en");
options.SupportedCultures = SupportedCultures;
options.SupportedUICultures = SupportedCultures;
});
// ...
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("en"),
SupportedCultures = SupportedCultures,
SupportedUICultures = SupportedCultures,
RequestCultureProviders = new List<IRequestCultureProvider>
{
new QueryStringRequestCultureProvider(),
new CookieRequestCultureProvider()
}
});
Resources\Language.cs:
public sealed class Language
{
public sealed class Login
{
public const string PageTitle = nameof(Login) + nameof(PageTitle);
public const string SubmitButton = nameof(Login) + nameof(SubmitButton);
public const string Username = nameof(Login) + nameof(Username);
// ...
}
}
查看:
@inject IHtmlLocalizer<Language> Localizer
...
@Localizer[Language.Login.SubmitButton]
我还有以下包含密钥和文本的 resx 文件。
Resources\Language.resx(也尝试使用名称 Language.en.resx 无济于事)
Resources\Language.fr.resx
所有文本都简单地显示为键,无论它是否源自 MVC 视图、Razor 页面、任意 class 从 DI 获取本地化程序或属性。
关于我做错了什么的任何线索?谢谢
这可能是多种情况。
您可以尝试将 .resx
文件重命名为:
Resources\Language.en-US.resx
你可以尝试使用类似@Localizer[Language.Login.SubmitButton].Value
的东西。
您也可以尝试为每个视图创建特定的 .resx
文件:
遵守规则是这样的:
- 使用视图程序集名称创建
.resx
文件。喜欢:Views.Login.Index.en-US.resx
- 在您的视图中注入 ViewLocalizer
@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
- 然后将它与字符串值一起使用,例如:
@Localizer["SubmitButton"].Value
甚至只是 @Localizer["SubmitButton"]
我还会将启动代码更改为更直接的代码
services.AddLocalization(options => options.ResourcesPath = "YourResourcesPath");
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("pt-BR"),
new CultureInfo("es-ES")
};
options.DefaultRequestCulture = new RequestCulture("YourDefaultCulture");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
});
希望以上内容对您有所帮助。
因此,最终证明 Language.cs
文件的位置在这里很重要。将它放在 Resources
文件夹中会导致某些东西被破坏(即使没有使用该文件夹的命名空间),而将它放在项目根目录中则没有问题。
我不太确定为什么这很重要 - 如果我能找到答案,我会编辑这个答案。
编辑:感谢@Grimm 找到答案。这确实是 .net core 3.1 中的一个错误,详见 https://github.com/dotnet/aspnetcore/issues/17733
我在让文本本地化在 ASP.NET Core 3 中工作时遇到了一些问题。或者更确切地说,它以前是工作的,但由于一次事故(没有隐藏更改并意外删除了其中的一些)它不再做。我确定我遗漏了一些基本的东西,但我可以终生解决。
我已经准备好以下代码块:
Startup.cs:
private static readonly List<CultureInfo> SupportedCultures = new List<CultureInfo>
{
new CultureInfo("en"),
new CultureInfo("fr")
};
// ...
services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix, opts => { opts.ResourcesPath = "Resources"; })
.AddDataAnnotationsLocalization(options =>
{
options.DataAnnotationLocalizerProvider = (type, factory) =>
factory.Create(typeof(Language));
})
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
});
services.AddLocalization(o =>
{
o.ResourcesPath = "Resources";
});
services.Configure<RequestLocalizationOptions>(options =>
{
options.DefaultRequestCulture = new RequestCulture("en", "en");
options.SupportedCultures = SupportedCultures;
options.SupportedUICultures = SupportedCultures;
});
// ...
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("en"),
SupportedCultures = SupportedCultures,
SupportedUICultures = SupportedCultures,
RequestCultureProviders = new List<IRequestCultureProvider>
{
new QueryStringRequestCultureProvider(),
new CookieRequestCultureProvider()
}
});
Resources\Language.cs:
public sealed class Language
{
public sealed class Login
{
public const string PageTitle = nameof(Login) + nameof(PageTitle);
public const string SubmitButton = nameof(Login) + nameof(SubmitButton);
public const string Username = nameof(Login) + nameof(Username);
// ...
}
}
查看:
@inject IHtmlLocalizer<Language> Localizer
...
@Localizer[Language.Login.SubmitButton]
我还有以下包含密钥和文本的 resx 文件。
Resources\Language.resx(也尝试使用名称 Language.en.resx 无济于事)
Resources\Language.fr.resx
所有文本都简单地显示为键,无论它是否源自 MVC 视图、Razor 页面、任意 class 从 DI 获取本地化程序或属性。
关于我做错了什么的任何线索?谢谢
这可能是多种情况。
您可以尝试将 .resx
文件重命名为:
Resources\Language.en-US.resx
你可以尝试使用类似@Localizer[Language.Login.SubmitButton].Value
的东西。
您也可以尝试为每个视图创建特定的 .resx
文件:
遵守规则是这样的:
- 使用视图程序集名称创建
.resx
文件。喜欢:Views.Login.Index.en-US.resx
- 在您的视图中注入 ViewLocalizer
@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
- 然后将它与字符串值一起使用,例如:
@Localizer["SubmitButton"].Value
甚至只是@Localizer["SubmitButton"]
我还会将启动代码更改为更直接的代码
services.AddLocalization(options => options.ResourcesPath = "YourResourcesPath");
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("pt-BR"),
new CultureInfo("es-ES")
};
options.DefaultRequestCulture = new RequestCulture("YourDefaultCulture");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
});
希望以上内容对您有所帮助。
因此,最终证明 Language.cs
文件的位置在这里很重要。将它放在 Resources
文件夹中会导致某些东西被破坏(即使没有使用该文件夹的命名空间),而将它放在项目根目录中则没有问题。
我不太确定为什么这很重要 - 如果我能找到答案,我会编辑这个答案。
编辑:感谢@Grimm 找到答案。这确实是 .net core 3.1 中的一个错误,详见 https://github.com/dotnet/aspnetcore/issues/17733