在.NET Core项目中也是可以使用.resx资源文件,来为程序提供多语言支持。以下我们就以一个.NET Core控制台项目为例,来讲解资源文件的使用。

新建一个.NET Core控制台项目,然后我们在其中新建一个.resx资源文件叫DemoResource.resx

注意.resx资源文件默认是Internal访问级别的,这会导致其它程序集无法访问资源文件类,所以我们最好将其改为Public访问级别

然后我们在资源文件DemoResource.resx中定义一个字符串叫"Message",值为"Hello",如下所示:

由于资源文件是支持多语言的,其文件名命名格式如下:

{资源文件名}.{语言文化名称}.resx

其中{语言文化名称}就是诸如:zh-CN、en-US、ja-JP等语言字符串,代表了一种特定的语言,例如zh-CN就是简体中文。

所以现在我们就为资源文件DemoResource.resx再创造两种语言:

DemoResource.zh-CN.resx,简体中文资源文件:

DemoResource.ja-JP.resx,日语资源文件:

所以我们现在,就有三个资源文件:

  • DemoResource.resx是默认的资源文件,我们将其内部的字符串Message定义为了英文。
  • DemoResource.zh-CN.resx是简体中文资源文件,我们将其内部的字符串Message定义为了简体中文。
  • DemoResource.ja-JP.resx是日语资源文件,我们将其内部的字符串Message定义为了日语。

其实它们代表的都是DemoResource资源文件,只不过是不同的语言版本罢了,现在项目结构如下所示:

好了,现在定义好了资源文件,我们就来看看怎么使用它们。

在.NET Core中.resx资源文件是和线程的语言相关,其主要和当前线程的如下两个语言属性相关:

  • Thread.CurrentThread.CurrentCulture
  • Thread.CurrentThread.CurrentUICulture

如果当前线程的这两个属性是什么语言,那么.resx资源文件就会返回对应语言的内容。

首先我们在.NET Core控制台项目的Main方法中,设置当前线程的CurrentCulture和CurrentUICulture为zh-CN:

static void Main(string[] args)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-CN");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("zh-CN"); Console.WriteLine($"Message为:{DemoResource.Message}"); Console.WriteLine("按任意键结束...");
Console.ReadKey();
}

运行结果如下,我们可以看到显示的Message为中文"你好"

现在我们将当前线程的CurrentCulture和CurrentUICulture设置为ja-JP:

static void Main(string[] args)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("ja-JP");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("ja-JP"); Console.WriteLine($"Message为:{DemoResource.Message}"); Console.WriteLine("按任意键结束...");
Console.ReadKey();
}

运行结果如下,我们可以看到显示的Message为日文"こんにちは"

然后,我们将当前线程的CurrentCulture和CurrentUICulture设置为fr-FR,代表法语:

static void Main(string[] args)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR"); Console.WriteLine($"Message为:{DemoResource.Message}"); Console.WriteLine("按任意键结束...");
Console.ReadKey();
}

那么现在结果是什么呢,如下所示:

可能很多同学会觉得很奇怪为什么Message显示的是英语"Hello"。其实道理很简单,因为我们没有定义DemoResource.fr-FR.resx这个法语资源文件啊,所以在当前线程的CurrentCulture和CurrentUICulture为fr-FR时,调用DemoResource.Message时,.NET Core只好使用DemoResource默认资源文件DemoResource.resx的内容,所以DemoResource.Message输出的是英文"Hello"。

其实资源文件类DemoResource也是可以通过设置其Culture属性来指定使用某一种特定的语言,如下代码所示,虽然我们设置当前线程的CurrentCulture和CurrentUICulture为ja-JP,但是由于我们设置了DemoResource.Culture为zh-CN:

static void Main(string[] args)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("ja-JP");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("ja-JP"); DemoResource.Culture = new CultureInfo("zh-CN"); Console.WriteLine($"Message为:{DemoResource.Message}"); Console.WriteLine("按任意键结束...");
Console.ReadKey();
}

所以最后显示的Message为中文"你好"

Async和Await模式对线程语言的影响

有的同学可能会想.NET Core中的Async和Await模式,会对Thread.CurrentThread.CurrentCulture和Thread.CurrentThread.CurrentUICulture这两个线程的语言属性产生影响吗。

我们来看看如下代码:

/// <summary>
/// 测试Async和Await模式,是否会对Thread.CurrentThread.CurrentCulture和Thread.CurrentThread.CurrentUICulture产生影响
/// </summary>
static void AsyncAwaitThreadCulture()
{
//设置主线程的CurrentCulture和CurrentUICulture为语言ja-JP
Thread.CurrentThread.CurrentCulture = new CultureInfo("ja-JP");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("ja-JP"); Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>主线程的CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); //通过Task来启动第一层线程
Task.Run(async () =>
{
Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>第一层线程的CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); //通过Task来启动第二层线程
Task task = Task.Run(() =>
{
Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>第二层线程的CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); //通过Thread来启动第三层线程
Thread th = new Thread(new ThreadStart(() =>
{ Thread.Sleep(); Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>第三层线程的CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}");
})); th.IsBackground = true;
th.Start(); th.Join();//阻塞第二层线程,直到第三层线程th结束
}); Thread.Sleep(); Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>await之前CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); await task;//await,直到第二层线程结束 Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>await之后CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); }).Wait();//阻塞主线程,直到第一层线程执行完毕
}

运行结果如下所示:

我们在AsyncAwaitThreadCulture方法中,将主线程的CurrentCulture和CurrentUICulture设置为了ja-JP,结果可以发现后续启动的线程其CurrentCulture和CurrentUICulture也都为ja-JP

现在我们设置主线程的CurrentCulture和CurrentUICulture为ja-JP,但是将第一层线程的CurrentCulture和CurrentUICulture改为zh-CN

/// <summary>
/// 测试Async和Await模式,是否会对Thread.CurrentThread.CurrentCulture和Thread.CurrentThread.CurrentUICulture产生影响
/// </summary>
static void AsyncAwaitThreadCulture()
{
//设置主线程的CurrentCulture和CurrentUICulture为语言ja-JP
Thread.CurrentThread.CurrentCulture = new CultureInfo("ja-JP");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("ja-JP"); Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>主线程的CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); //通过Task来启动第一层线程
Task.Run(async () =>
{
//将第一层线程的CurrentCulture和CurrentUICulture改为zh-CN
Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-CN");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("zh-CN"); Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>第一层线程的CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); //通过Task来启动第二层线程
Task task = Task.Run(() =>
{
Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>第二层线程的CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); //通过Thread来启动第三层线程
Thread th = new Thread(new ThreadStart(() =>
{ Thread.Sleep(); Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>第三层线程的CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}");
})); th.IsBackground = true;
th.Start(); th.Join();//阻塞第二层线程,直到第三层线程th结束
}); Thread.Sleep(); Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>await之前CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); await task;//await,直到第二层线程结束 Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>await之后CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); }).Wait();//阻塞主线程,直到第一层线程执行完毕
}

现在运行结果如下:

我们可以看到从第一层线程开始,后续启动线程的CurrentCulture和CurrentUICulture都为zh-CN了

这说明在.NET Core中,默认情况下线程的CurrentCulture和CurrentUICulture属性是由启动它的线程来决定的,上面的结果很明显由于第一层线程的CurrentCulture和CurrentUICulture为zh-CN,所以由第一层线程启动的后续线程(第二层和第三层线程)也都为zh-CN。所以在.NET Core中要设置线程的CurrentCulture和CurrentUICulture属性,最简单的办法就是在根线程(主线程)上设置CurrentCulture和CurrentUICulture的语言即可。

最后如果是在ASP.NET Core中,只需要写一个中间件(Middleware),来更改主线程的CurrentCulture和CurrentUICulture属性为特定语言,即可实现.resx资源文件的全局利用,当然ASP.NET Core中也有一套自带的资源文件匹配规则,这里大家觉得怎么用起来方便怎么用即可。

本文示例源代码

.NET Core中多语言支持的更多相关文章

  1. ASP.NET Core 中的 WebSocket 支持(转自MSDN)

    本文介绍 ASP.NET Core 中 WebSocket 的入门方法. WebSocket (RFC 6455) 是一个协议,支持通过 TCP 连接建立持久的双向信道. 它用于从快速实时通信中获益的 ...

  2. 使用Novell.Directory.Ldap.NETStandard在.NET Core中验证AD域账号

    Novell.Directory.Ldap.NETStandard是一个在.NET Core中,既支持Windows平台,又支持Linux平台,进行Windows AD域操作的Nuget包. 首先我们 ...

  3. 在Asp.net Core中使用中间件来管理websocket

    介绍 ASP.NET Core SignalR是一个有用的库,可以简化Web应用程序中实时通信的管理.但是,我宁愿使用WebSockets,因为我想要更灵活,并且与任何WebSocket客户端兼容. ...

  4. 【asp.net core 系列】14 .net core 中的IOC

    0.前言 通过前面几篇,我们了解到了如何实现项目的基本架构:数据源.路由设置.加密以及身份验证.那么在实现的时候,我们还会遇到这样的一个问题:当我们业务类和数据源越来越多的时候,我们无法通过普通的构造 ...

  5. 在ASP.NET Core中使用Apworks开发数据服务:对HAL的支持

    HAL,全称为Hypertext Application Language,它是一种简单的数据格式,它能以一种简单.统一的形式,在API中引入超链接特性,使得API的可发现性(discoverable ...

  6. 在ASP.NET Core中如何支持每个租户数据存储策略的数据库

    在ASP.NET Core中如何支持每个租户数据存储策略的数据库 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: ht ...

  7. C# 嵌入dll 动软代码生成器基础使用 系统缓存全解析 .NET开发中的事务处理大比拼 C#之数据类型学习 【基于EF Core的Code First模式的DotNetCore快速开发框架】完成对DB First代码生成的支持 基于EF Core的Code First模式的DotNetCore快速开发框架 【懒人有道】在asp.net core中实现程序集注入

    C# 嵌入dll   在很多时候我们在生成C#exe文件时,如果在工程里调用了dll文件时,那么如果不加以处理的话在生成的exe文件运行时需要连同这个dll一起转移,相比于一个单独干净的exe,这种形 ...

  8. JVM中的动态语言支持简介

    抽丝剥茧 细说架构那些事——[优锐课] 从版本6开始,JVM已扩展为支持现代动态语言(也称为脚本语言).Java8的发行为这一领域提供了更多动力.感到这种支持的必要性是因为Java作为一种语言固有地是 ...

  9. [.NET Core]ASP.NET Core中如何解决接收表单时的不支持的媒体类型(HTTP 415 Unsupported Media Type)错误呢?

    [.NET Core]ASP.NET Core中如何解决接收表单时的不支持的媒体类型(HTTP 415 Unsupported Media Type)错误呢? 在ASP.NET Core应用程序中,接 ...

随机推荐

  1. 更新oracle数据库表如何实现主键自增长

     在数据库中实现主键自动增长有利于我们做数据插入操作,在SQL SERVER上创建表时可以在int类型的字段后加上identity(1,1),该字段就会从1开始,按照+1的方式自增,将这个字段设置 ...

  2. 深入理解net core中的依赖注入、Singleton、Scoped、Transient(四)

    相关文章: 深入理解net core中的依赖注入.Singleton.Scoped.Transient(一) 深入理解net core中的依赖注入.Singleton.Scoped.Transient ...

  3. Webservice和EJB

    WebService Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯 ...

  4. SASS 入门

    为什么使用Sass 作为前端(html.javascript.css)的三大马车之一的css,一直以静态语言存在,HTML5火遍大江南北了.javascript由于NODE.JS而成为目前前后端统一开 ...

  5. 分享:将WDCP中的PHP5.2 1.7升级到PHP 5.3的方法

    将wdcp中php 5.2.17升级到php 5.3方法: 1.首先下载wdcp php5.3升级脚本 wget http://down.wdlinux.cn/in/php_up53.sh 2.进行安 ...

  6. 使用 PowerShell 创建 Linux 虚拟机

    Azure PowerShell 模块用于从 PowerShell 命令行或脚本创建和管理 Azure 资源. 本指南详细介绍了如何使用 Azure PowerShell 模块部署运行 Ubuntu ...

  7. TableView的cell加载倒计时重用问题解决方案

    TableView的cell加载倒计时重用问题解决方案 效果 说明 1. 写过类似需求的朋友一定知道,TableView上面加载倒计时功能会遇到复杂的重用问题难以解决 2. 本人提供一种解决思路,高效 ...

  8. Sql Server 支持的数据类型

    T-SQL语言和SQLServer数据库中的数据通常需要定义一个数据类型,数据类型定义了对象可以容纳的数据的种类. 哪些对象需要数据类型 (1).表和视图的列:                 在定义 ...

  9. 多个Firefox共存&&彻底关闭自动更新

    安装 0x001 下载好要安装Firefox的版本 可到Firefox官方仓库下载 https://ftp.mozilla.org/pub/firefox/releases/ 我下载的是42和56版 ...

  10. 获取URL网页信息

    static string GetHtml(string url) {string strHTML = ""; WebClient myWebClient = new WebCli ...