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。

配置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, 并设置其值为“你好”。

在Controller中获取本地化字符串

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

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

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

下面我们修改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, 结果如下

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

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

我们期望的“你好”被正确输出了,这说明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

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

这说明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, 结果如下

如何在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字段,其值为"再见"

使用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, 结果如下

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

本地化字符串读取成功

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

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

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

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

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

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

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

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

  4. .NetCore技术研究-EntityFramework Core 3.0 Preview

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

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

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

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

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

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

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

  8. .Net Core 全球化&本地化的使用

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

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

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

随机推荐

  1. 2018-2019-2 网络对抗技术 20165220 Exp2 后门原理与实践

    实验内容 1.使用netcat获取主机操作Shell,cron启动2.使用socat获取主机操作Shell, 任务计划启动3.使用MSF meterpreter(或其他软件)生成可执行文件,利用nca ...

  2. JIRA

    https://www.jianshu.com/p/8c14b52ce692 JIRA这个工具接触有好几年了,在多个海外项目上都用过这个工具.去年又在项目上深度使用后就有点爱不释手了,回国后也在找机会 ...

  3. CentOS7配置mailx使用外部smtp服务器发送邮件

    转自huskiesir的博客: 发送邮件的两种方式: 1.连接现成的smtp服务器去发送(此方法比较简单,直接利用现有的smtp服务器比如qq.新浪.网易等邮箱,只需要直接配置mail.rc文件即可实 ...

  4. hcna(华为)_Telnet篇

    Telnet提供了一个交互式操作界面,允许终端远程登录到任何可以充当 Telnet服务器的设备.Telnet用户可以像通过Console口本地登录一样对 设备进行操作.远端Telnet服务器和终端之间 ...

  5. HBase shell scan 过滤器用法总结

    比较器: 前面例子中的regexstring:2014-11-08.*.binary:\x00\x00\x00\x05,这都是比较器.HBase的filter有四种比较器: (1)二进制比较器:如’b ...

  6. python中的单向循环链表实现

    引子 所谓单向循环链表,不过是在单向链表的基础上,如响尾蛇般将其首尾相连,也因此有诸多类似之处与务必留心之点.尤其是可能涉及到头尾节点的操作,不可疏忽. 对于诸多操所必须的遍历,这时的条件是什么?又应 ...

  7. 31 ArcGIS中后缀一览表(持续更新中……)

  8. framework7 入门(数据获取和传递)

    数据获取 framework7自带request方法 , var app = new Framework7({...});app.request(parameters) 或者 Framework7.r ...

  9. 小程序页面跳转传参参数值为url时参数时 会出现丢失

    当参数的值为url的时候,  ?号   _  下划线   等等 都会被 截取掉,看不到,  这样在 另一个页面 options中  截取的url就不完全 let url="http://ba ...

  10. PTA第四次作业

    题目 7-1 计算职工工资 1.设计思路 (1)第一步:观察题意了解各个参数与所需函数在题目中的意义: 第二步:设计算法编写函数,让函数的功能实现题目中所需的功能: 第三步:运行程序检测是否错误. ( ...