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

作者: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. 在“解决方案资源管理器”中,右键单击将包含资源文件的文件夹,然后选择“添加”>“新项”。

    Nested contextual menu: In Solution Explorer, a contextual menu is open for Resources. A second contextual menu is open for Add showing the New Item command highlighted.

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

    Add New Item dialog

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

    Welcome.es.resx file (the Welcome resource file for Spanish) with the word Hello in the Name column and the word Hola (Hello in Spanish) in the Value column

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

    Solution Explorer showing the Welcome Spanish (es) resource file

资源文件命名

资源名称是类的完整类型名称减去程序集名称。 例如,类 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 设置为“资源”,因此主控制器的法语资源文件的项目相对路径是 Resources/Controllers.HomeController.fr.resx。 或者,你可以使用文件夹组织资源文件。 对于主控制器,该路径将为 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. 在“解决方案资源管理器”中,右键单击将包含资源文件的文件夹,然后选择“添加”>“新项”。

    Nested contextual menu: In Solution Explorer, a contextual menu is open for Resources. A second contextual menu is open for Add showing the New Item command highlighted.

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

    Add New Item dialog

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

    Welcome.es.resx file (the Welcome resource file for Spanish) with the word Hello in the Name column and the word Hola (Hello in Spanish) in the Value column

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

    Solution Explorer showing the Welcome Spanish (es) resource file

资源文件命名

资源名称是类的完整类型名称减去程序集名称。 例如,类 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 设置为“资源”,因此主控制器的法语资源文件的项目相对路径是 Resources/Controllers.HomeController.fr.resx。 或者,你可以使用文件夹组织资源文件。 对于主控制器,该路径将为 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(西班牙语/墨西哥)。

后续步骤

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

其他资源