在 ASP.NET Core 应用中针对语言和区域性提供本地化资源

注意

此版本不是本文的最新版本。 对于当前版本,请参阅此文的 .NET 8 版本

警告

此版本的 ASP.NET Core 不再受支持。 有关详细信息,请参阅 .NET 和 .NET Core 支持策略。 对于当前版本,请参阅此文的 .NET 8 版本

重要

此信息与预发布产品相关,相应产品在商业发布之前可能会进行重大修改。 Microsoft 对此处提供的信息不提供任何明示或暗示的保证。

对于当前版本,请参阅此文的 .NET 8 版本

作者:Rick AndersonDamien BowdenBart CalixtoNadeem AfanaHisham Bin Ateya

本地化应用的一项任务是在资源文件中提供本地化字符串。 本文介绍如何使用资源文件。

SupportedCulturesSupportedUICultures

ASP.NET Core 有两个区域性值的集合,即 SupportedCulturesSupportedUICulturesSupportedCulturesCultureInfo 对象可决定区域性相关函数的结果,如日期、时间、数字和货币格式等。 SupportedCultures 确定文本的排序顺序、大小写约定和字符串比较。 有关服务器如何获取区域性的详细信息,请参阅 StringComparer.CurrentCultureSupportedUICultures 可确定按 ResourceManager 查找的转换字符串(位于 .resx 文件中)。 ResourceManager 只需查找 CurrentUICulture 决定的区域性特定字符串。 .NET 中的每个线程都具有 CurrentCultureCurrentUICulture 对象。 呈现区域性相关函数时,ASP.NET Core 可检查这些值。 例如,如果当前线程的区域性设置为“en-US”(英语,美国),DateTime.Now.ToLongDateString() 将显示“Thursday, February 18, 2016”,但如果 CurrentCulture 设置为“es-ES”(西班牙语,西班牙),则输出将为“jueves,18 de febrero de 2016”。

资源文件

注意:ResX 查看器和编辑器提供了使用 Visual Studio Code 处理资源文件的备用机制。

资源文件是将可本地化的字符串与代码分离的有用机制。 非默认语言的转换字符串在 .resx 资源文件中单独显示。 例如,你可能想要创建一个包含转换字符串、名为 Welcome.es.resx 的西班牙语资源文件。 “es”是西班牙语的语言代码。 要在 Visual Studio 中创建此资源文件,请支持以下操作:

  1. 在“解决方案资源管理器”中,右键单击将包含资源文件的文件夹,然后选择“添加”>“新项”。

    嵌套的上下文菜单:在“解决方案资源管理器”中,“资源”可打开上下文菜单。“添加”可打开第二个上下文菜单,突出显示“新项”命令。

  2. 在“搜索已安装的模板”框中,输入“资源”并命名该文件。

    “添加新项”对话框

  3. 在“名称”列中输入键值(本机字符串),在“值”列中输入转换字符串 。

    Welcome.es.resx 文件(西班牙语版 Welcome 资源文件)的单词 Hello 位于“名称”列,Hola(西班牙语版 Hello)位于“值”列

    Visual Studio 将显示 Welcome.es.resx 文件。

    显示 Welcome Spanish (es) 资源文件的解决方案资源管理器

资源文件命名

资源名称是类的完整类型名称减去程序集名称。 例如,类 LocalizationWebsite.Web.Startup 的主要程序集为 LocalizationWebsite.Web.dll 的项目中的法语资源将命名为 Startup.fr.resx。 类 LocalizationWebsite.Web.Controllers.HomeController 的资源将命名为 Controllers.HomeController.fr.resx。 如果目标类的命名空间与将需要完整类型名称的程序集名称不同。 例如,在示例项目中,类型 ExtraNamespace.Tools 的资源将命名为 ExtraNamespace.Tools.fr.resx。

在示例项目中,ConfigureServices 方法将 ResourcesPath 设置为“资源”,因此 home 控制器的法语资源文件的项目相对路径是 Resources/Controllers.HomeController.fr.resx。 或者,你可以使用文件夹组织资源文件。 对于 home 控制器,该路径将为 Resources/Controllers/HomeController.fr.resx。 如果不使用 ResourcesPath 选项,.resx 文件将转到项目的基目录中。 HomeController 的资源文件将命名为 Controllers.HomeController.fr.resx。 是选择使用圆点还是路径命名约定,具体取决于你想如何组织资源文件。

资源名称 圆点或路径命名
Resources/Controllers.HomeController.fr.resx
Resources/Controllers/HomeController.fr.resx 路径

Razor 视图中使用 @inject IViewLocalizer 的资源文件遵循类似的模式。 可以使用圆点命名或路径命名约定对视图的资源文件进行命名。 Razor 视图资源文件可模拟其关联视图文件的路径。 假设我们将 ResourcesPath 设置为“Resources”,与 Views/Home/About.cshtml 视图关联的法语资源文件可能是下面其中之一:

  • Resources/Views/Home/About.fr.resx

  • Resources/Views.Home.About.fr.resx

如果不使用 ResourcesPath 选项,视图的 .resx 文件将位于视图所在的文件夹。

RootNamespaceAttribute

RootNamespaceAttribute 属性在程序集的根命名空间不同于程序集名称时,提供程序集的根命名空间。

警告

当项目名称不是有效的 .NET 标识符时,可能会发生这种情况。 例如,my-project-name.csproj 将使用根命名空间 my_project_name 和导致此错误的程序集名称 my-project-name

如果程序集的根命名空间不同于程序集名称:

  • 默认情况下无法进行本地化。
  • 因程序集内搜索资源的方式导致本地化失败。 RootNamespace 是生成时间值,不可用于正在执行的进程。

如果 RootNamespace 不同于 AssemblyName,请在 AssemblyInfo.cs 中包括以下内容(参数值替换为实际值):

using System.Reflection;
using Microsoft.Extensions.Localization;

[assembly: ResourceLocation("Resource Folder Name")]
[assembly: RootNamespace("App Root Namespace")]

上述代码可成功解析 resx 文件。

区域性回退行为

在搜索资源时,本地化会进行“区域性回退”。 从所请求的区域性开始,如果未能找到,则还原至该区域性的父区域性。 另外,CultureInfo.Parent 属性代表父区域性。 这通常(但并不是总是)意味着从语言和区域性代码中移除区域签名。 例如,墨西哥的西班牙语方言为“es-MX”。 它具备一个父级“es”西班牙,没有特别指定国家/地区。

假设你的站点接收到了一个区域性为“fr-CA”的“Welcome”资源的请求。 本地化系统按顺序查找以下资源,并选择第一个匹配项:

  • Welcome.fr-CA.resx
  • Welcome.fr.resx
  • Welcome.resx(如果 NeutralResourcesLanguage 为“fr-CA”)

例如,如果删除了“.fr”区域性指示符,而且已将区域性设置为“法语”,将读取默认资源文件,并本地化字符串。 对于不满足所请求区域性的情况,资源管理器可指定默认资源或回退资源。 缺少适用于请求区域性的资源时,如果只想返回键,不得具有默认资源文件。

使用 Visual Studio 生成资源文件

如果在 Visual Studio 中创建文件名没有区域性的资源文件(例如 Welcome.resx),Visual Studio 将创建一个 C# 类,并且具有每个字符串的属性。 这通常不是你想在 ASP.NET Core 中使用的。 你通常没有默认的 .resx 资源文件(没有区域性名称的 .resx 文件) 。 建议创建具有区域性名称(例如 Welcome.fr.resx)的 .resx 文件 。 创建具有区域性名称的 .resx 文件时,Visual Studio 不会生成类文件。

添加其他区域性

每个语言和区域性组合(除默认语言外)都需要唯一资源文件。 通过新建语言代码属于名称一部分的资源文件,为不同的区域性和区域设置创建资源文件(例如,en-us、fr-ca 和 en-gb)。 这些代码位于文件名和 .resx 文件扩展名之间,如 Welcome.es-MX.resx(西班牙语/墨西哥)。

后续步骤

本地化应用还涉及以下任务:

其他资源

作者:Rick AndersonDamien BowdenBart CalixtoNadeem AfanaHisham Bin Ateya

本地化应用的一项任务是在资源文件中提供本地化字符串。 本文介绍如何使用资源文件。

SupportedCulturesSupportedUICultures

ASP.NET Core 有两个区域性值的集合,即 SupportedCulturesSupportedUICulturesSupportedCulturesCultureInfo 对象可决定区域性相关函数的结果,如日期、时间、数字和货币格式等。 SupportedCultures 确定文本的排序顺序、大小写约定和字符串比较。 有关服务器如何获取区域性的详细信息,请参阅 StringComparer.CurrentCultureSupportedUICultures 可确定按 ResourceManager 查找的转换字符串(位于 .resx 文件中)。 ResourceManager 只需查找 CurrentUICulture 决定的区域性特定字符串。 .NET 中的每个线程都具有 CurrentCultureCurrentUICulture 对象。 呈现区域性相关函数时,ASP.NET Core 可检查这些值。 例如,如果当前线程的区域性设置为“en-US”(英语,美国),DateTime.Now.ToLongDateString() 将显示“Thursday, February 18, 2016”,但如果 CurrentCulture 设置为“es-ES”(西班牙语,西班牙),则输出将为“jueves,18 de febrero de 2016”。

资源文件

资源文件是将可本地化的字符串与代码分离的有用机制。 非默认语言的转换字符串在 .resx 资源文件中单独显示。 例如,你可能想要创建一个包含转换字符串、名为 Welcome.es.resx 的西班牙语资源文件。 “es”是西班牙语的语言代码。 要在 Visual Studio 中创建此资源文件,请支持以下操作:

  1. 在“解决方案资源管理器”中,右键单击将包含资源文件的文件夹,然后选择“添加”>“新项”。

    嵌套的上下文菜单:在“解决方案资源管理器”中,“资源”可打开上下文菜单。“添加”可打开第二个上下文菜单,突出显示“新项”命令。

  2. 在“搜索已安装的模板”框中,输入“资源”并命名该文件。

    “添加新项”对话框

  3. 在“名称”列中输入键值(本机字符串),在“值”列中输入转换字符串 。

    Welcome.es.resx 文件(西班牙语版 Welcome 资源文件)的单词 Hello 位于“名称”列,Hola(西班牙语版 Hello)位于“值”列

    Visual Studio 将显示 Welcome.es.resx 文件。

    显示 Welcome Spanish (es) 资源文件的解决方案资源管理器

资源文件命名

资源名称是类的完整类型名称减去程序集名称。 例如,类 LocalizationWebsite.Web.Startup 的主要程序集为 LocalizationWebsite.Web.dll 的项目中的法语资源将命名为 Startup.fr.resx。 类 LocalizationWebsite.Web.Controllers.HomeController 的资源将命名为 Controllers.HomeController.fr.resx。 如果目标类的命名空间与将需要完整类型名称的程序集名称不同。 例如,在示例项目中,类型 ExtraNamespace.Tools 的资源将命名为 ExtraNamespace.Tools.fr.resx。

在示例项目中,ConfigureServices 方法将 ResourcesPath 设置为“资源”,因此 home 控制器的法语资源文件的项目相对路径是 Resources/Controllers.HomeController.fr.resx。 或者,你可以使用文件夹组织资源文件。 对于 home 控制器,该路径将为 Resources/Controllers/HomeController.fr.resx。 如果不使用 ResourcesPath 选项,.resx 文件将转到项目的基目录中。 HomeController 的资源文件将命名为 Controllers.HomeController.fr.resx。 是选择使用圆点还是路径命名约定,具体取决于你想如何组织资源文件。

资源名称 圆点或路径命名
Resources/Controllers.HomeController.fr.resx
Resources/Controllers/HomeController.fr.resx 路径

Razor 视图中使用 @inject IViewLocalizer 的资源文件遵循类似的模式。 可以使用圆点命名或路径命名约定对视图的资源文件进行命名。 Razor 视图资源文件可模拟其关联视图文件的路径。 假设我们将 ResourcesPath 设置为“Resources”,与 Views/Home/About.cshtml 视图关联的法语资源文件可能是下面其中之一:

  • Resources/Views/Home/About.fr.resx

  • Resources/Views.Home.About.fr.resx

如果不使用 ResourcesPath 选项,视图的 .resx 文件将位于视图所在的文件夹。

RootNamespaceAttribute

RootNamespaceAttribute 属性在程序集的根命名空间不同于程序集名称时,提供程序集的根命名空间。

警告

当项目名称不是有效的 .NET 标识符时,可能会发生这种情况。 例如,my-project-name.csproj 将使用根命名空间 my_project_name 和导致此错误的程序集名称 my-project-name

如果程序集的根命名空间不同于程序集名称:

  • 默认情况下无法进行本地化。
  • 因程序集内搜索资源的方式导致本地化失败。 RootNamespace 是生成时间值,不可用于正在执行的进程。

如果 RootNamespace 不同于 AssemblyName,请在 AssemblyInfo.cs 中包括以下内容(参数值替换为实际值):

using System.Reflection;
using Microsoft.Extensions.Localization;

[assembly: ResourceLocation("Resource Folder Name")]
[assembly: RootNamespace("App Root Namespace")]

上述代码可成功解析 resx 文件。

区域性回退行为

在搜索资源时,本地化会进行“区域性回退”。 从所请求的区域性开始,如果未能找到,则还原至该区域性的父区域性。 另外,CultureInfo.Parent 属性代表父区域性。 这通常(但并不是总是)意味着从语言和区域性代码中移除区域签名。 例如,墨西哥的西班牙语方言为“es-MX”。 它具备一个父级“es”西班牙,没有特别指定国家/地区。

假设你的站点接收到了一个区域性为“fr-CA”的“Welcome”资源的请求。 本地化系统按顺序查找以下资源,并选择第一个匹配项:

  • Welcome.fr-CA.resx
  • Welcome.fr.resx
  • Welcome.resx(如果 NeutralResourcesLanguage 为“fr-CA”)

例如,如果删除了“.fr”区域性指示符,而且已将区域性设置为“法语”,将读取默认资源文件,并本地化字符串。 对于不满足所请求区域性的情况,资源管理器可指定默认资源或回退资源。 缺少适用于请求区域性的资源时,如果只想返回键,不得具有默认资源文件。

使用 Visual Studio 生成资源文件

如果在 Visual Studio 中创建文件名没有区域性的资源文件(例如 Welcome.resx),Visual Studio 将创建一个 C# 类,并且具有每个字符串的属性。 这通常不是你想在 ASP.NET Core 中使用的。 你通常没有默认的 .resx 资源文件(没有区域性名称的 .resx 文件) 。 建议创建具有区域性名称(例如 Welcome.fr.resx)的 .resx 文件 。 创建具有区域性名称的 .resx 文件时,Visual Studio 不会生成类文件。

添加其他区域性

每个语言和区域性组合(除默认语言外)都需要唯一资源文件。 通过新建语言代码属于名称一部分的资源文件,为不同的区域性和区域设置创建资源文件(例如,en-us、fr-ca 和 en-gb)。 这些代码位于文件名和 .resx 文件扩展名之间,如 Welcome.es-MX.resx(西班牙语/墨西哥)。

后续步骤

本地化应用还涉及以下任务:

其他资源