ASP.NET Core Blazor 全球化和本地化ASP.NET Core Blazor globalization and localization

Razor 组件可供位于不同区域、使用不同语言的用户使用。Razor components can be made accessible to users in multiple cultures and languages. 以下 .NET 全球化和本地化方案可用:The following .NET globalization and localization scenarios are available:

  • .NET 资源系统.NET's resources system
  • 特定于区域性的数字和日期格式Culture-specific number and date formatting

当前支持有限的 ASP.NET Core 本地化方案:A limited set of ASP.NET Core's localization scenarios are currently supported:

有关详细信息,请参阅 ASP.NET Core 全球化和本地化For more information, see ASP.NET Core 全球化和本地化.

全球化Globalization

Blazor 的 @bind 功能基于用户的当前区域性执行格式并分析值以进行显示。Blazor's @bind functionality performs formats and parses values for display based on the user's current culture.

可从 System.Globalization.CultureInfo.CurrentCulture 属性访问当前区域性。The current culture can be accessed from the System.Globalization.CultureInfo.CurrentCulture property.

CultureInfo.InvariantCulture 用于以下字段类型(<input type="{TYPE}" />):CultureInfo.InvariantCulture is used for the following field types (<input type="{TYPE}" />):

  • date
  • number

上述字段类型:The preceding field types:

  • 使用其基于浏览器的相应格式规则进行显示。Are displayed using their appropriate browser-based formatting rules.
  • 不能包含自由格式的文本。Can't contain free-form text.
  • 基于浏览器的实现提供用户交互特性。Provide user interaction characteristics based on the browser's implementation.

以下字段类型具有特定的格式要求且当前不受 Blazor 支持,因为所有主流浏览器均不支持它们:The following field types have specific formatting requirements and aren't currently supported by Blazor because they aren't supported by all major browsers:

  • datetime-local
  • month
  • week

@bind 支持 @bind:culture 参数,以提供用于分析值并设置值格式的 System.Globalization.CultureInfo@bind supports the @bind:culture parameter to provide a System.Globalization.CultureInfo for parsing and formatting a value. 使用 datenumber 字段类型时,不建议指定区域性。Specifying a culture isn't recommended when using the date and number field types. datenumber 具有可提供所需区域性的内置 Blazor 支持。date and number have built-in Blazor support that provides the required culture.

本地化Localization

Blazor WebAssembly

Blazor WebAssembly 应用使用用户的语言首选项设置区域性。Blazor WebAssembly apps set the culture using the user's language preference.

若要显式配置区域性,请在 Program.Main 中设置 CultureInfo.DefaultThreadCurrentCultureCultureInfo.DefaultThreadCurrentUICultureTo explicitly configure the culture, set CultureInfo.DefaultThreadCurrentCulture and CultureInfo.DefaultThreadCurrentUICulture in Program.Main.

默认情况下,Blazor WebAssembly 携带在用户区域性中显示值(如日期和货币)所需的最小全球化资源。By default, Blazor WebAssembly carries minimal globalization resources required to display values, such as dates and currency, in the user's culture. 必须支持动态更改区域性的应用程序应在项目文件中配置 BlazorWebAssemblyLoadAllGlobalizationDataApplications that must support dynamically changing the culture should configure BlazorWebAssemblyLoadAllGlobalizationData in the project file:

<PropertyGroup>
  <BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>

还可以通过传递给 Blazor.start 的选项将 Blazor WebAssembly 配置为使用特定应用程序区域性启动。Blazor WebAssembly can also be configured to launch using a specific application culture using options passed to Blazor.start. 例如,下面的示例显示配置为使用 en-GB 区域性启动的应用:For instance, the sample below shows an app configured to launch using the en-GB culture:

<script src="_framework/blazor.webassembly.js" autostart="false"></script>
<script>
  Blazor.start({
    applicationCulture: 'en-GB'
  });
</script>

applicationCulture 的值应符合 BCP-47 语言标记格式The value for applicationCulture should conform to the BCP-47 language tag format.

如果应用不需要本地化,你可以将应用配置为支持不变区域性,这基于 en-US 区域性:If the app doesn't require localization, you may configure the app to support the invariant culture, which is based on the en-US culture:

<PropertyGroup>
  <InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>

默认情况下,Blazor WebAssembly 应用的中间语言 (IL) 链接器配置去除国际化信息(显式请求的区域设置除外)。By default, the Intermediate Language (IL) Linker configuration for Blazor WebAssembly apps strips out internationalization information except for locales explicitly requested. 有关详细信息,请参阅 配置 ASP.NET Core Blazor 链接器For more information, see 配置 ASP.NET Core Blazor 链接器.

虽然 Blazor 默认选择的区域性可能足以满足大多数用户的需求,但请考虑为用户提供一种指定其首选区域设置的方法。While the culture that Blazor selects by default might be sufficient for most users, consider offering a way for users to specify their preferred locale. 如需获取具有区域性选取器的 Blazor WebAssembly 示例应用,请参阅 LocSample 本地化示例应用。For a Blazor WebAssembly sample app with a culture picker, see the LocSample localization sample app.

Blazor Server

Blazor Server 应用使用本地化中间件进行本地化。Blazor Server apps are localized using Localization Middleware. 中间件为从应用请求资源的用户选择相应的区域性。The middleware selects the appropriate culture for users requesting resources from the app.

可使用以下方法之一设置区域性:The culture can be set using one of the following approaches:

有关更多信息和示例,请参见ASP.NET Core 全球化和本地化For more information and examples, see ASP.NET Core 全球化和本地化.

CookiesCookies

本地化区域性 cookie 可以保留用户的区域性。A localization culture cookie can persist the user's culture. 本地化中间件会在后续请求上读取 cookie,以设置用户的区域性。The Localization Middleware reads the cookie on subsequent requests to set the user's culture.

使用 cookie 可确保 WebSocket 连接可以正确地传播区域性。Use of a cookie ensures that the WebSocket connection can correctly propagate the culture. 如果本地化方案基于 URL 路径或查询字符串,则该方案可能无法与 Websocket 协同使用,因而无法保留区域性。If localization schemes are based on the URL path or query string, the scheme might not be able to work with WebSockets, thus fail to persist the culture. 因此,建议的方式是使用本地化区域性 cookie。Therefore, use of a localization culture cookie is the recommended approach.

如果在本地化 cookie 中保留了区域性,则可以使用任意方法来分配区域性。Any technique can be used to assign a culture if the culture is persisted in a localization cookie. 如果该应用已经为服务器端 ASP.NET Core 建立了本地化方案,请继续使用应用的现有本地化基础结构,并在应用方案中设置本地化区域性 cookie。If the app already has an established localization scheme for server-side ASP.NET Core, continue to use the app's existing localization infrastructure and set the localization culture cookie within the app's scheme.

下面的示例演示如何在可由本地化中间件读取的 cookie 中设置当前区域性。The following example shows how to set the current culture in a cookie that can be read by the Localization Middleware. Pages/_Host.cshtml 文件中的开始 <body> 标记内立即创建一个 Razor 表达式:Create a Razor expression in the Pages/_Host.cshtml file immediately inside the opening <body> tag:

@using System.Globalization
@using Microsoft.AspNetCore.Localization

...

<body>
    @{
        this.HttpContext.Response.Cookies.Append(
            CookieRequestCultureProvider.DefaultCookieName,
            CookieRequestCultureProvider.MakeCookieValue(
                new RequestCulture(
                    CultureInfo.CurrentCulture,
                    CultureInfo.CurrentUICulture)));
    }

    ...
</body>

本地化由应用按以下事件顺序进行处理:Localization is handled by the app in the following sequence of events:

  1. 浏览器向应用发送初始 HTTP 请求。The browser sends an initial HTTP request to the app.
  2. 本地化中间件分配区域性。The culture is assigned by the Localization Middleware.
  3. _Host 页面 (_Host.cshtml) 中的 Razor 表达式将区域性作为响应的一部分保留在 cookie 中。The Razor expression in the _Host page (_Host.cshtml) persists the culture in a cookie as part of the response.
  4. 浏览器打开 WebSocket 连接以创建交互式 Blazor Server 会话。The browser opens a WebSocket connection to create an interactive Blazor Server session.
  5. 本地化中间件读取 cookie 并分配区域性。The Localization Middleware reads the cookie and assigns the culture.
  6. Blazor Server 会话以正确的区域性开始。The Blazor Server session begins with the correct culture.

使用 RazorPage 时,请使用 Context 属性:When working with a RazorPage, use the Context property:

@{
    this.Context.Response.Cookies.Append(
        CookieRequestCultureProvider.DefaultCookieName,
        CookieRequestCultureProvider.MakeCookieValue(
            new RequestCulture(
                CultureInfo.CurrentCulture,
                CultureInfo.CurrentUICulture)));
}

提供用于选择区域性的 UIProvide UI to choose the culture

若要提供支持用户选择区域性的 UI,建议使用基于重定向的方法。To provide UI to allow a user to select a culture, a redirect-based approach is recommended. 此过程与用户尝试访问安全资源时 Web 应用中发生的情况类似。The process is similar to what happens in a web app when a user attempts to access a secure resource. 用户会被重定向到登录页面,然后再重定向到原始资源。The user is redirected to a sign-in page and then redirected back to the original resource.

应用通过重定向到控制器来保留用户的所选区域性。The app persists the user's selected culture via a redirect to a controller. 控制器将用户选择的区域性设置为 cookie,然后将用户重定向回原始 URI。The controller sets the user's selected culture into a cookie and redirects the user back to the original URI.

在服务器上创建一个 HTTP 终结点,以在 cookie 中设置用户的所选区域性,并执行重定向回原始 URI:Establish an HTTP endpoint on the server to set the user's selected culture in a cookie and perform the redirect back to the original URI:

[Route("[controller]/[action]")]
public class CultureController : Controller
{
    public IActionResult SetCulture(string culture, string redirectUri)
    {
        if (culture != null)
        {
            HttpContext.Response.Cookies.Append(
                CookieRequestCultureProvider.DefaultCookieName,
                CookieRequestCultureProvider.MakeCookieValue(
                    new RequestCulture(culture)));
        }

        return LocalRedirect(redirectUri);
    }
}

警告

使用 LocalRedirect 操作结果以阻止开放式重定向攻击。Use the LocalRedirect action result to prevent open redirect attacks. 有关详细信息,请参阅 阻止 ASP.NET Core 中的开放重定向攻击For more information, see 阻止 ASP.NET Core 中的开放重定向攻击.

如果应用未配置为处理控制器操作:If the app isn't configured to process controller actions:

  • 将 MVC 服务添加到 Startup.ConfigureServices 中的服务集合:Add MVC services to the service collection in Startup.ConfigureServices:

    services.AddControllers();
    
  • Startup.Configure 中添加控制器终结点路由:Add controller endpoint routing in Startup.Configure:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToPage("/_Host");
    });
    

以下组件显示了一个示例,说明如何在用户选择区域性时执行初始重定向:The following component shows an example of how to perform the initial redirection when the user selects a culture:

@inject NavigationManager NavigationManager

<h3>Select your language</h3>

<select @onchange="OnSelected">
    <option>Select...</option>
    <option value="en-US">English</option>
    <option value="fr-FR">Français</option>
</select>

@code {
    private void OnSelected(ChangeEventArgs e)
    {
        var culture = (string)e.Value;
        var uri = new Uri(NavigationManager.Uri)
            .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
        var query = $"?culture={Uri.EscapeDataString(culture)}&" +
            $"redirectUri={Uri.EscapeDataString(uri)}";

        NavigationManager.NavigateTo("/Culture/SetCulture" + query, forceLoad: true);
    }
}

其他资源Additional resources