ASP.NET Core Web API 中的本地化





5.00/5 (3投票s)
如何在 ASP.NET Core Web API 6 中进行本地化
本地化是一个非常重要的话题,当您计划构建一个面向多个文化和语言的应用程序或网站时。您必须准备好您的应用程序或网站,以根据用户的相关文化显示所有信息,这对于实现更广泛的受众至关重要。
想象一下,您正在为讲阿拉伯语的国家构建一个应用程序,但应用程序的主要语言是英语。这样,您的应用程序对您的目标市场的大部分人来说将没有用处,您将显著失去受众,因此您的应用程序将被抛弃,用户也不会回头。
您的内容本地化程度越高,您的应用程序或网站的可用性就越好。您应该始终以完全本地化为目标,以确保与您的产品进行无缝交互。
在本教程中,我们将学习如何在 ASP.NET Core Web API 中应用本地化,通过添加阿拉伯语资源文件。我们将使用最新版本的 .NET 6 和 Visual Studio 2022 构建 RESTful API,因此请先安装 VS 2022,然后再继续本教程。最后,我们将使用 Postman 测试 API。
创建本地化项目
启动 Visual Studio 2022 并创建一个新项目 – ASP.NET Core Web API
给它起一个名字,比如‘LocalizationInAspNetCoreWebApi’
然后选择 .NET 6 并按 创建。
一如既往,请确保删除模板中的 WeatherForecast
控制器和实体。
ASP.NET Core Web API 本地化的 3 个步骤
现在,要将本地化应用于 ASP.NET Core Web API 项目,有三个主要步骤需要遵循:
- 将本地化集成到 API 项目中间件中
- 添加所需的本地化资源文件
- 使用
IStringLocalizer
访问资源文件
现在,让我们在教程中详细解释每一步。
1. 将本地化集成到 API 中间件
我们需要让 ASP.NET Core Web API 知道我们将进行本地化,通过指定选项,其中资源文件的路径将位于我们稍后在本教程中创建的 Resources 文件夹中。
因此,让我们在 CreateBuilder(args)
调用之后添加以下代码:
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
此外,我们必须将本地化配置注入到 API 中间件中,以便它能够理解我们正在尝试本地化到哪个文化,当然,如果您针对两种或多种文化进行本地化,您可以指定多种区域性。
在您的 program.cs 文件中,让我们在 builder.build()
方法调用之后添加以下代码:
var supportedCultures = new[] { "en-US", "ar" };
var localizationOptions =
new RequestLocalizationOptions().SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
在这里,我们说明我们将支持两种文化或区域性,即“en-US
”和“ar
”,其中“en-US
”将是默认值,除非 HTTP 请求没有其他指示。
2. 添加所需的本地化资源文件
在本教程中,我们将学习两种方法来创建和使用 ASP.NET Core Web API 中的资源文件:
- 使用控制器资源结构
- 使用共享资源结构
让我们在项目下创建一个名为‘Resources
’的新文件夹。
我们将在此文件夹中存放所有 .resx 文件。
使用控制器资源结构
通过使用控制器资源结构,您可以为每个控制器分配一个资源文件,这将允许您将资源结构化和分区到多个文件中。
在此之前,让我们确保我们已创建控制器,以便我们可以创建与其名称匹配的资源文件。
在您的 Controllers 文件夹中,添加一个名为 PostsController
的新控制器,并将其设为一个空的 API 控制器。
现在,暂时保留此控制器。稍后我们将回来开发它,以便它可以从资源文件中读取。
在您的 Resources 文件夹中,右键单击并创建一个名为‘Controllers’的新文件夹,在该新‘Controllers’文件夹内,创建一个名为‘PostsController.ar.resx’的新 Resource
。
这将作为 posts 控制器的阿拉伯语本地化文件。在 ASP.NET Core 中,无需为默认区域性或文化添加本地化文件,因为在本地化文件中,您将拥有与默认值相同的名称,而值将是本地化后的值。如果 StringLocalizer
无法找到给定 string
的条目,则将返回 string
本身。
此外,您无需通过 StringLocalizer
以外的其他方式访问资源文件。
现在回到我们的新资源文件。在此文件中,让我们添加一些示例数据,以便稍后能够测试我们的工作。
让我们看看资源文件夹的样子:
您也可以从 Resources 文件夹中删除 Controllers 文件夹,并依赖点命名结构,这样资源文件名将包含 Controllers 作为前缀,如下所示:
Resources\Controllers.PostsController.ar.resx
但是,我更喜欢使用文件夹结构,因为它看起来更整洁,更易读。
使用共享资源结构
通过这种方式,我们可以依赖单个文件来包含所有本地化条目,因此该文件可以在多个控制器或其他类之间使用。
让我们添加一个名为 SharedResource.ar.resx 的新资源文件。
为了保持简单,我们将添加与之前在 PostsController 资源文件中添加的相同条目。
现在,为了使其真正作为共享资源工作,我们需要创建一个同名的空类或虚拟类‘SharedResource
’,并且我们应该将其放置在 Resources 文件夹之外的某个地方,我们可以创建一个名为 Entities 的新文件夹放在项目下,然后将其放在那里。
namespace LocalizationInAspNetCoreWebApi
{
public class SharedResource
{
}
}
我们已经准备好了所需的本地化文件,有两种方式,现在是时候看看如何从控制器中使用和访问这些资源了。
3. 使用 IStringLocalizer 访问资源文件
最后一步将是访问这些资源文件,这可以通过 Controller
的构造函数注入到 ASP.NET Core 中的 IStringLocalizer
来实现。
让我们看看 PostsController
的以下代码:
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
namespace LocalizationInAspNetCoreWebApi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class PostsController : ControllerBase
{
private readonly IStringLocalizer<PostsController> stringLocalizer;
private readonly IStringLocalizer<SharedResource> sharedResourceLocalizer;
public PostsController(IStringLocalizer<PostsController> postsControllerLocalizer,
IStringLocalizer<SharedResource> sharedResourceLocalizer)
{
this.stringLocalizer = postsControllerLocalizer;
this.sharedResourceLocalizer = sharedResourceLocalizer;
}
/// <summary>
/// This endpoint will access the PostsController
/// Resource to retrieve the localized data ...
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("PostsControllerResource")]
public IActionResult GetUsingPostsControllerResource()
{
var article = stringLocalizer["Article"];
var postName = stringLocalizer.GetString("Welcome").Value ?? "";
return Ok(new { PostType = article.Value, PostName = postName });
}
/// <summary>
/// This endpoint will access the SharedResourece to retrieve the localized data ...
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("SharedResource")]
public IActionResult GetUsingSharedResource()
{
var article = sharedResourceLocalizer["Article"];
var postName = sharedResourceLocalizer.GetString("Welcome").Value ?? "";
return Ok(new { PostType = article.Value, PostName = postName });
}
}
}
首先,在构造函数中,我们注入了两个 IStringLocalizer
实例:一个将用于访问 PostsController 资源文件,另一个实例将访问 SharedResource 文件,请注意每个实例使用的类型有所不同。
接下来,我们定义了两个端点,以便能够展示 PostsController 资源与共享资源之间的访问差异。
此外,我们可以通过使用字典的键名或使用 GetString
方法来访问资源文件条目。两者都有效并返回相同的结果。
如果搜索的条目名称不存在于资源字典中,stringLocalizer
将返回一个 ResourceNotFound true
的标志。
运行项目,确保浏览器显示您的端点的 Swagger 文档。
在 Postman 中进行测试
打开 Postman 并创建一个新请求,将其分配给您运行应用程序后得到的 URL 以及您的 api/method
路由,并在标头中添加 Accept-Language
标头,值为‘ar
’。
PostsController 资源 – ar
PostsController 资源 – en
共享资源 – ar
共享资源 – en
在响应标头中添加 Content-Language
最后一项要测试的是将 Content-Language
添加到响应标头中,这主要用于向用户描述响应的内容语言。
打开 program 文件,在 app.UseRequestLocalization(localizationOptions)
之前添加以下行:
localizationOptions.ApplyCurrentCultureToResponseHeaders = true;
再次运行您的 API,然后切换回 Postman。
尝试调用其中一个 API 请求。
注意,一旦端点返回结果,在 Response 部分的 Headers 选项卡中,您将看到一个名为 Content-Language 的新标头,其值为‘ar
’,这意味着返回的内容是 ar 区域性的。
摘要
在本教程中,我们学习了如何在 ASP.NET Core Web API 6 中进行本地化。我们实现了三个步骤来实现本地化:将本地化配置应用于中间件、创建所需的资源文件,最后使用 IStringLocalizer
访问资源文件的条目。
此外,我们了解到有两种方法可以为控制器添加资源文件:控制器结构资源和共享资源,在本教程中,我们实现了这两种策略,并创建了两个端点来访问每个资源文件的资源。
最终,我们设法使用 Postman 测试了所有用例,并且还测试了将 Content-Language
标头应用于响应,以便我们可以广播或告知用户响应是以所请求的区域性返回的。
本地化应该在多个层面上进行;在 UI 上,您应该确保本地化所有标签、占位符、标题、前端验证消息等。然后在 API 端,您必须确保返回带有代码和消息的正确异常,以便 UI 可以将代码翻译成 UI 上的本地化消息。此外,您的 API 应该为任何需要的翻译字符串定义带有预期本地化的资源文件,最后,您应该为本地化的固定或不常更改的内容(如国家、城市、类别、类型等)保留单独的表。
如果您正在做一个大型产品,您可能需要咨询专业的文案撰写人或营销专家,以咨询并为您提供针对目标文化的最佳本地化策略,并准备文化上准确的本地化文本和措辞,让目标用户能够自然地理解。
参考文献
您可以在我的 GitHub 帐户 中找到代码。
有关 ASP.NET Core 中本地化的更多信息,您可以查看 Microsoft 的官方文档。
有关本地化的一般性进一步阅读,您可以 查看这篇文章。
奖励
享受钢琴天才“肖邦”的诗意旋律 – 华尔兹 Op.69 No.2,由 弗拉基米尔·阿什肯纳齐 演奏
文章 ASP.NET Core Web API 中的本地化 最先出现在 Coding Sonata。