在 ASP.NET Core 应用中针对语言和区域性提供本地化资源
注意
此版本不是本文的最新版本。 对于当前版本,请参阅此文的 .NET 8 版本。
警告
此版本的 ASP.NET Core 不再受支持。 有关详细信息,请参阅 .NET 和 .NET Core 支持策略。 对于当前版本,请参阅此文的 .NET 8 版本。
作者:Rick Anderson、Damien Bowden、Bart Calixto、Nadeem Afana 和 Hisham Bin Ateya
本地化应用的一项任务是在资源文件中提供本地化字符串。 本文介绍如何使用资源文件。
SupportedCultures
和 SupportedUICultures
ASP.NET Core 有两个区域性值的集合,即 SupportedCultures
和 SupportedUICultures
。 SupportedCultures
的 CultureInfo 对象可决定区域性相关函数的结果,如日期、时间、数字和货币格式等。 SupportedCultures
确定文本的排序顺序、大小写约定和字符串比较。 有关服务器如何获取区域性的详细信息,请参阅 StringComparer.CurrentCulture。 SupportedUICultures
可确定按 ResourceManager 查找的转换字符串(位于 .resx 文件中)。 ResourceManager
只需查找 CurrentUICulture
决定的区域性特定字符串。 .NET 中的每个线程都具有 CurrentCulture
和 CurrentUICulture
对象。 呈现区域性相关函数时,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 中创建此资源文件,请支持以下操作:
在“解决方案资源管理器”中,右键单击将包含资源文件的文件夹,然后选择“添加”>“新项”。
在“搜索已安装的模板”框中,输入“资源”并命名该文件。
在“名称”列中输入键值(本机字符串),在“值”列中输入转换字符串 。
Visual Studio 将显示 Welcome.es.resx 文件。
资源文件命名
资源名称是类的完整类型名称减去程序集名称。 例如,类 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 Anderson、Damien Bowden、Bart Calixto、Nadeem Afana 和 Hisham Bin Ateya
本地化应用的一项任务是在资源文件中提供本地化字符串。 本文介绍如何使用资源文件。
SupportedCultures
和 SupportedUICultures
ASP.NET Core 有两个区域性值的集合,即 SupportedCultures
和 SupportedUICultures
。 SupportedCultures
的 CultureInfo 对象可决定区域性相关函数的结果,如日期、时间、数字和货币格式等。 SupportedCultures
确定文本的排序顺序、大小写约定和字符串比较。 有关服务器如何获取区域性的详细信息,请参阅 StringComparer.CurrentCulture。 SupportedUICultures
可确定按 ResourceManager 查找的转换字符串(位于 .resx 文件中)。 ResourceManager
只需查找 CurrentUICulture
决定的区域性特定字符串。 .NET 中的每个线程都具有 CurrentCulture
和 CurrentUICulture
对象。 呈现区域性相关函数时,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 中创建此资源文件,请支持以下操作:
在“解决方案资源管理器”中,右键单击将包含资源文件的文件夹,然后选择“添加”>“新项”。
在“搜索已安装的模板”框中,输入“资源”并命名该文件。
在“名称”列中输入键值(本机字符串),在“值”列中输入转换字符串 。
Visual Studio 将显示 Welcome.es.resx 文件。
资源文件命名
资源名称是类的完整类型名称减去程序集名称。 例如,类 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(西班牙语/墨西哥)。
后续步骤
本地化应用还涉及以下任务: