深入研究.NET Core的本地化机制

时间:2023-02-24 12:43:13

ASP.NET Core中提供了一些本地化服务和中间件,可将网站本地化为不同的语言文化。

ASP.NET Core中我们可以使用Microsoft.AspNetCore.Localization库来实现本地化。

在.NET Core 2.0以上版本, Microsoft.AspNetCore.Localization已经包含在了Microsoft.AspNetCore.All中,所以我们并不需要手动引入其他的类库。

创建一个MVC网站

为了测试ASP.NET Core的本地化,我们首先在Visual Studio 2017中创建一个MVC项目LocalizationSample。

深入研究.NET Core的本地化机制

配置Startup类

ASP.NET Core中,如果希望启动本地化,首先需要在Startup类的ConfigureServices方法中使用services.AddLocalization添加本地化服务。

public void ConfigureServices(IServiceCollection services)
{
services.AddLocalization(o =>
{
o.ResourcesPath = "Resources";
}); services.AddMvc();
}

在这个方法中,我们指定了文件夹Resources作为存放翻译文件的目录。

注: 如果不指定存放翻译文件的目录, ASP.NET Core会默认从网站根目录下读取。

然后我们需要在Configure方法中添加本地化中间件。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseStaticFiles(); IList<CultureInfo> supportedCultures = new List<CultureInfo>
{
new CultureInfo("en-US"),
new CultureInfo("zh-CN"),
};
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("en-US"),
SupportedCultures = supportedCultures,
SupportedUICultures = supportedCultures
}); app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
  • app.UseRequestLocalization必须放置app.UseMvc之前
  • DefaultRequestCulture参数指定了默认的语言文化,即用户不指定任何文化时的默认语言文化
  • SupportedCulturesSupportedUICultures是指定当前应用支持的所有语言文化

注: SupportedCultures指定的是数字和日期格式, SupportedUICultures指定的翻译文件

添加资源文件

下面我们尝试添加一个资源文件

  1. 首先我们创建一个Resources文件夹,这就是我们在前面Startup类中配置的目录名。
  2. 然后我们在Resource文件夹中添加一个资源文件,并命名为Controllers.HomeController.zh-CN.resx。
  3. 在这个资源文件中,添加一个字段Hello, 并设置其值为“你好”。

深入研究.NET Core的本地化机制

在Controller中获取本地化字符串

现在我们打开默认生成的HomeController, 清空里面所有的action, 并添加一个新的action, 代码如下:

public class HomeController : Controller
{
public HomeController()
{ } public IActionResult Hello()
{
return Content("Hello");
}
}

启动项目之后访问/Home/Hello, 结果如下

深入研究.NET Core的本地化机制

下面我们修改HomeController的代码, 来引入本地化字符串访问器

public class HomeController : Controller
{
private readonly IStringLocalizer<HomeController> _localizer; public HomeController(IStringLocalizer<HomeController> localizer)
{
_localizer = localizer;
} public IActionResult Hello()
{
return Content(_localizer["Hello"]);
}
}

代码解释

  • IStringLocalizer是一个本地化字符串访问器的泛型接口,这里我们通过依赖注入的方式在HomeController的构造函数中将其注入
  • 我们可以通过IStringLocalizer的属性访问器获取到对应字段在不同语言下的文本。

最终效果

现在我们启动程序, 重新访问/Home/Hello, 结果如下

深入研究.NET Core的本地化机制

你会发现结果没有变化,这是因为默认我们设置的语言文化是en-US, 但是我们之前没有添加en-US的资源文件,所以程序就直接将访问的字段名输出了。

现在我们修改URL, 访问/Home/Hello?ui-culture=zh-CN, 结果如下

深入研究.NET Core的本地化机制

我们期望的“你好”被正确输出了,这说明ASP.NET Core默认支持在Url中以culture参数的形式设置当前网站使用的语言文化。

资源文件命名

为什么我们之前添加了一个名为Controllers.HomeController.zh-CN.resx的资源文件,本地化字符串访问器IStringLocalizer就能定位到这个文件并读取其中的字段属性呢?

这是由ASP.NET Core资源文件的命名约定决定的。

ASP.NET Core资源文件的名称由2部分组成:

  • 去掉程序集名称的完整类名
  • 语言文化名称

以前面的例子为例:

我们创建了一个本地化字符串访问器接口,它的泛型类型是HomeController, 其完整类名是LocalizationSample.Controllers.HomeController, 当前程序集的名称是LocalizationSample, 所以去掉程序集名称之后,剩余部分是Controllers.HomeController。当我们设置culture参数是zh-CN时, ASP.NET Core查找的资源文件名是Controllers.HomeController.zh-CN.resx, 这正是我们前面添加的中文语言文化资源文件名。

如果你不喜欢这种方式,ASP.NET Core还提供了另外一种资源文件的组织方式

你可以Resources目录下创建以下目录结构

  • Resources
    • Controllers
      • HomeController.zh-CN.resx

本地化字符串访问器也能自动定位到这个文件。

默认的语言文化提供器

ASP.NET Core的本地化中间件默认支持3种语言文化提供器

  • URL中的查询字符串
  • Cookie
  • 请求头

URL中的查询字符串

ASP.NET Core会从URL中的culture参数中获取当前应用使用的语言文化,这就是前面例子中,“你好”能正确输出的原因

除了指定ui-culture参数,你还可以使用culture参数指定当前格式化时间,数字等所使用的语言文化。

?culture=zh-CN&ui-culture=zh-CN

?culture=zh-CN

?ui-culture=zh-CN

Tips: 当只指定culture或ui-culture参数时,ASP.NET Core会自动将culture和ui-culture设置成一样的。即?culture=zh-CN等同于?culture=zh-CN&ui-culture=zh-CN

Cookie

ASP.NET Core中还支持使用Cookie的方式设置当前应用使用的语言文化。默认使用的Cookie名称是.AspNetCore.Culture。

.AspNetCore.Culture的值格式如下

c=zh-CN|uic=zh-CN

c=zh-CN

uic=zh-CN

其中c表示culture, uic表示ui-culture。

下面我们使用Chrome的开发者工具, 为当前网页添加语言文化Cookie

深入研究.NET Core的本地化机制

然后我们访问/Home/Hello, "你好"也被正确的输出了

深入研究.NET Core的本地化机制

这说明ASP.NET Core从Cookie中读取到了语言文化配置

请求头

除了URL查询字符串和Cookie, ASP.NET Core还支持在请求头中指定语言文化。请求头中语言文化字段名称是 Accept-Language。

Accept-Language的文档,参见https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Accept-Language

这里我们使用Postman来测试一下,我们设置Accept-Language为zh-CN, zh;q=0.9, 结果如下

深入研究.NET Core的本地化机制

如何在View中使用本地化

除了Controller, 我们更多的是在View中使用本地化。

如果希望在View中使用本地化,首先需要在Startup类的ConfigureServices方法中启用View本地化。

public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix);
}

这里LanguageViewLocationExpanderFormat支持2种方式,这个和前面Controller的本地化文件名称约定类似

  • Suffix, 例/Resources/Home/Hello.zh-CN.resx
  • Path, 例/Resources/Home/zh-CN/Hello.resx

下面我们修改HomeController的代码,Hello方法将返回一个View

HomeController

public IActionResult Hello()
{
//return Content(_localizer["Hello"]);
return View();
}

Hello.cshtml


@{
ViewData["Title"] = "Hello";
} <h2>Good Bye</h2>

然后我们创建如下图的目录结构, 并创建资源文件Hello.zh-CN.resx, 并添加GoodBye字段,其值为"再见"

深入研究.NET Core的本地化机制

深入研究.NET Core的本地化机制

使用ViewLocalizer

ViewLocalizer类可以帮助我们在Razor视图中使用本地化文本。现在我们来修改Hello.cshtml, 在文件添加本地化引用,并注入一个ViewLocalizer对象

@using Microsoft.AspNetCore.Mvc.Localization

@inject IViewLocalizer Localizer
@{
ViewData["Title"] = "Hello";
} <h2>@Localizer["GoodBye"]</h2>

这里我们使用ViewLocalizer读取了本地化文本,它的用法和IStringLocalier一样,都是通过属性访问器访问对应字段的本地化文本。

最终效果

现在我们运行程序并访问/Home/Hello, 结果如下

深入研究.NET Core的本地化机制

然后我们继续访问/Home/Hello?ui-culture=zh-CN, 结果如下

深入研究.NET Core的本地化机制

本地化字符串读取成功

本篇源代码 https://github.com/lamondlu/aspnetcore_localizationsample

深入研究.NET Core的本地化机制的更多相关文章

  1. 集群环境下,你不得不注意的ASP&period;NET Core Data Protection 机制

    引言 最近线上环境遇到一个问题,就是ASP.NET Core Web应用在单个容器使用正常,扩展多个容器无法访问的问题.查看容器日志,发现以下异常: System.Security.Cryptogra ...

  2. &period;Net core 的热插拔机制的深入探索&comma;以及卸载问题求救指南&period;

    .Net core 的热插拔机制的深入探索,以及卸载问题求救指南. 一.依赖文件*.deps.json的读取. 依赖文件内容如下.一般位于编译生成目录中 { "runtimeTarget&q ...

  3. 深入研究EF Core AddDbContext 引起的内存泄露的原因

    前两天逛园子,看到 @Jeffcky 发的这篇文章<EntityFramework Core依赖注入上下文方式不同造成内存泄漏了解一下>. 一开始只是粗略的扫了一遍没仔细看,只是觉得是多次 ...

  4. &period;NetCore技术研究-EntityFramework Core 3&period;0 Preview

    前段时间.Net Core 3.0 发布了,Entity Framework Core 3.0 也发布了Preview版.假期用了一上午大致研究了一遍,同时又体验了一把Visual Studio 20 ...

  5. C&num;入门篇6-8:字符串操作 深入研究字符串的内存驻留机制

    //字符串的内存驻留机制 public static void Test() { //当有多个字符串变量包含了同样的字符串实际值时, //CLR可能不会为它们重复地分配内存,而是让它们统统指向同一个字 ...

  6. 深入研究React setState的工作机制

    前言 上个月发表了一篇 React源码学习--ReactClass,但是后来我发现,大家对这种大量贴代码分析源码的形式并不感冒.讲道理,我自己看着也烦,还不如自己直接去翻源码来得痛快.吸取了上一次的教 ...

  7. 【Java深入研究】4、fail-fast机制

    在JDK的Collection中我们时常会看到类似于这样的话: 例如,ArrayList: 注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证.快速失 ...

  8. &period;Net Core 全球化&amp&semi;本地化的使用

    官网文档 nuget地址 创建资源文件 添加资源文件 实施策略 配置本地化 本地化中间件 使用 视图本地化 DataAnnotations 本地化 Make the app's content loc ...

  9. 【Java 线程的深入研究4】ThreadPoolExecutor运转机制详解

    hreadPoolExecutor机制 一.概述 1.ThreadPoolExecutor作为java.util.concurrent包对外提供基础实现,以内部线程池的形式对外提供管理任务执行,线程调 ...

随机推荐

  1. 利用私有的API获得手机上所安装的所有应用信息(包括版本,名称,bundleID,类型)

    MobileCoreService这个系统的库,里面有个私有的类LSApplicationWorkspace ,利用运行时可以获得私有类里面的方法,- (id)allInstalledApplicat ...

  2. listbox 多选删除(找了好多都不行,终于让我写出来了)

    方法一:两个for循环 aspx.cs private string id=""; protected void btn_del_Click(object sender, Even ...

  3. angularjs &plus; fis &plus;modJS 对于支持amd规范的组建处理&lpar;PhotoSwipe 支持,百度webUpload支持&rpar;

    这不是很好的处理方式,但是能够解决问题,希望有大神推荐更好的方式. 前端模块使用angularjs + fis +modJS 开发前端应用有两个月了.总结了以下的优点: fis 自动构建,自动发布,功 ...

  4. OGC学习课程

    1.引言 由于项目需要,需要学习OGC相关地图标准,包括WMS.WFS.GML.SLD等,只是国内相关书籍大家都懂的,特向Google大师请教,得一秘籍<Open Web Mapping> ...

  5. android之listview

    首先建立res/layout/data_list.xml: 代码如下: <?xml version="1.0" encoding="utf-8"?> ...

  6. http请求利器: 今天配置出了RESTClient,用MAVEN构建了UI运行包

  7. HDU 1887 Weird Numbers(负数的进制转化)

    题目要求有两种情况,第一种from情况,正常输出即可,很简单.第二种是to情况,给一个数字,输出负进制R的原码,这个有点小麻烦...解决方法如下; 首先,把这个数n按正常方式展开,形式如下: .... ...

  8. git 生成公钥、私钥方法与clone使用方法

    我的配置流程 Git配置 Git安装完之后,需做git配置.打开git bash,分别执行以下两句命令 git config --global user.name "用户名" gi ...

  9. Dora&period;Interception,为&period;NET Core度身打造的AOP框架 &lbrack;2&rsqb;:以约定的方式定义拦截器

    上一篇<更加简练的编程体验>提供了最新版本的Dora.Interception代码的AOP编程体验,接下来我们会这AOP框架的编程模式进行详细介绍,本篇文章着重关注的是拦截器的定义.采用“ ...

  10. H3C交换机限制子网之间的相互访问

    acl number 3000     rule 1 permit ip source 10.0.5.0 0.0.0.255 destination 172.16.1.100 0   #允许10.0. ...