如何设置默认区域性以便请求本地化在 ASP.NET Core 应用程序中工作?

问题描述 投票:0回答:1

我有一个名为 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.en-US.resx
    • SharedResource.es-ES.resx
    • 共享资源.fr-FR.resx

我在根文件夹中也有空类 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>
c# .net asp.net-core .net-core localization
1个回答
0
投票

根据文档

UseRequestLocalization 初始化一个RequestLocalizationOptions 对象。对于每个请求,都会枚举 RequestLocalizationOptions 中的 RequestCultureProvider 列表,并使用第一个能够成功确定请求区域性的提供程序。默认提供程序来自 RequestLocalizationOptions 类:

  1. QueryStringRequestCultureProvider
  2. CookieRequestCultureProvider
  3. AcceptLanguageHeaderRequestCultureProvider

默认情况下,浏览器会在请求标头中设置

Accept-language:en-US
,这会导致当您设置除 EN 之外的默认语言时本地化无法正常工作。

我建议您通过以下方式提供

RequestCultureProviders

  1. 不需要的话删除
    AcceptLanguageHeaderRequestCultureProvider
  2. RequestCultureProviders
    中指定提供程序的顺序(提供程序按从先到后的顺序执行)
  3. 如果方法 12 不适合您的场景,请构建您自己的请求提供程序来处理本地化。

对于我的情况,我使用方法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
实例时完成的默认区域性。

© www.soinside.com 2019 - 2024. All rights reserved.