我有一个名为 WebApplication2 的 Web 应用程序,我可以使用 URL 参数(如
?culture=fr-FR
)进行请求本地化,或者将应用程序默认语言设置为 fr-FR
,但不能同时使用两者。这是一个默认文化为 en-US
的版本,即使我尝试将其设置为 fr-FR
。
程序.cs
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
// Add localization services
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
string[] supportedCultures = [ "fr-FR", "en-US", "es-ES" ];
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
options.DefaultRequestCulture = new RequestCulture("fr-FR");
options.SetDefaultCulture("fr-FR")
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
var localizationOptions = app.Services.GetService<IOptions<RequestLocalizationOptions>>()?.Value;
if (localizationOptions != null)
{
localizationOptions.AddSupportedCultures(supportedCultures);
localizationOptions.DefaultRequestCulture = new RequestCulture("fr-FR");
app.UseRequestLocalization(localizationOptions);
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
另一个选项是将文化修复为
fr-FR
,但像 ?culture=en-US
这样的 URL 就不再起作用了。这可以通过对上面的代码示例进行以下更改来完成:
/* Comment these lines and replace it with single app.UseRequestLocalization call */
var localizationOptions = app.Services.GetService<IOptions<RequestLocalizationOptions>>()?.Value;
if (localizationOptions != null)
{
localizationOptions.AddSupportedCultures(supportedCultures);
localizationOptions.DefaultRequestCulture = new RequestCulture("fr-FR");
app.UseRequestLocalization(localizationOptions);
}
*/
/* This has effect but then URL like `?culture=en-US` doesn't work */
app.UseRequestLocalization("fr-FR");
请注意,本地化在这两种情况下都有效。正确的翻译显示在页面中。问题就像说,如果我希望具有文化的 URL 正常工作,我就不能使用除
en-US
之外的其他默认语言。
在项目根目录中有一个 Resources 文件夹,其中包含 3 个文件,每个文件只有 1 个字符串
StrLearnAbout
:
我在根文件夹中也有空类 SharedResource:
namespace WebApplication2
{
public class SharedResource
{
}
}
在 Index.cshtml 中
@using Microsoft.Extensions.Localization
@inject IStringLocalizer<SharedResource> Localizer
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1
<p>@Localizer["StrLearnAbout"]</p>
<p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
根据文档,
UseRequestLocalization 初始化一个RequestLocalizationOptions 对象。对于每个请求,都会枚举 RequestLocalizationOptions 中的 RequestCultureProvider 列表,并使用第一个能够成功确定请求区域性的提供程序。默认提供程序来自 RequestLocalizationOptions 类:
- QueryStringRequestCultureProvider
- CookieRequestCultureProvider
- AcceptLanguageHeaderRequestCultureProvider
默认情况下,浏览器会在请求标头中设置
Accept-language:en-US
,这会导致当您设置除 EN 之外的默认语言时本地化无法正常工作。
我建议您通过以下方式提供
RequestCultureProviders
:
AcceptLanguageHeaderRequestCultureProvider
RequestCultureProviders
中指定提供程序的顺序(提供程序按从先到后的顺序执行)对于我的情况,我使用方法2:
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
options.DefaultRequestCulture = new RequestCulture("fr-FR");
options.SetDefaultCulture("fr-FR")
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
options.RequestCultureProviders = new List<IRequestCultureProvider>
{
new QueryStringRequestCultureProvider(),
new CookieRequestCultureProvider()
};
});
此外,
对于您的
app.UseRequestLocalization();
代码,您可以将其转换为一行:
app.UseRequestLocalization(app.Services.GetService<IOptions<RequestLocalizationOptions>>().Value);
您不需要再次指定在添加/注册
RequestLocalizationOptions
实例时完成的默认区域性。