.NET Core中本地化机制的深入讲解
前言
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参数指定了默认的语言文化,即用户不指定任何文化时的默认语言文化
- supportedcultures和supporteduicultures是指定当前应用支持的所有语言文化
注: supportedcultures指定的是数字和日期格式, supporteduicultures指定的翻译文件
添加资源文件
下面我们尝试添加一个资源文件
- 首先我们创建一个resources文件夹,这就是我们在前面startup类中配置的目录名。
- 然后我们在resource文件夹中添加一个资源文件,并命名为controllers.homecontroller.zh-cn.resx。
- 在这个资源文件中,添加一个字段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, 结果如下
本地化字符串读取成功
本篇源代码 ()
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。