NetCore 之 多语言资源文件应用
当你的应用程序需要在多语言环境下运行时,资源文件(Resource)是必不可少的,ASP.NET Core 提供了一种基于资源文件(*.resx)的多语言实现方式,详细配置如下:
1、首先在application中添加测试资源文件
2、在Startup ConfigureServices中注册本地化所需的服务AddLocation,Configure<RequestLocalizationOptions> code如下:
1 builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); 2 builder.Services.Configure<RequestLocalizationOptions>(options => 3 { 4 var supportedCultures = new List<CultureInfo> 5 { 6 new CultureInfo("en"), 7 new CultureInfo("ja") 8 }; 9 options.DefaultRequestCulture = new RequestCulture(new CultureInfo("en")); 10 options.SupportedCultures = supportedCultures; 11 options.SupportedUICultures = supportedCultures; 12 options.AddInitialRequestCultureProvider(new CustomRequestCultureProvider(context => 13 { 14 var defaultLanguage = "ja";//"en"; 15 return Task.FromResult(new ProviderCultureResult(defaultLanguage, defaultLanguage))!; 16 })); 17 });
1 var requestLocalizationOptions = app.Services.GetService<IOptions<RequestLocalizationOptions>>(); 2 app.UseRequestLocalization(requestLocalizationOptions!.Value);
Notes:
1)、builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); //配置本地资源路径 Resources Folder。
2)、options.AddInitialRequestCultureProvider(new CustomRequestCultureProvider(context =>
{
var defaultLanguage = "en";
return Task.FromResult(new ProviderCultureResult(defaultLanguage, defaultLanguage))!;
}));//配置优先使用的本地化语言,这里用的是CustomRequestCultureProvider
ASP.NET Core 本地化默认共向我们提供了四种方式可用于当前请求的语言
- QueryStringRequestCultureProvider
- CookieRequestCultureProvider
- AcceptLanguageHeaderRequestCultureProvider
- CustomRequestCultureProvider
下面介绍下以上几种常用的方式,为了方便通过postman测试
- QueryStringRequestCultureProvider 需要在request url中指定ui-culture,例:https://localhost:5000/Resource/resourcedemo?ui-culture=ja
- AcceptLanguageHeaderRequestCultureProvider 在Requst请求头中添加accept-language
- CustomRequestCultureProvider 是我们默认使用的
*除此之外,如有特殊需要可以自定义RequestCultureProvider,例如创建MyCustomRequestCultureProvider
public class MyCustomRequestCultureProvider : RequestCultureProvider { private string _culture; private string _uiCulture; public MyCustomRequestCultureProvider(string culture, string uiCulture) { this._culture = culture; this._uiCulture = uiCulture; } public override Task<ProviderCultureResult?> DetermineProviderCultureResult(HttpContext httpContext) { return Task.FromResult(new ProviderCultureResult(_culture, _uiCulture)); } }
更改ConfigureService中配置:
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); builder.Services.Configure<RequestLocalizationOptions>(options => { var supportedCultures = new List<CultureInfo> { new CultureInfo("en"), new CultureInfo("ja") }; options.DefaultRequestCulture = new RequestCulture(new CultureInfo("en")); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; options.RequestCultureProviders = new IRequestCultureProvider[] { new MyCustomRequestCultureProvider("ja", "ja") }; //options.AddInitialRequestCultureProvider(new CustomRequestCultureProvider(context => //{ // var defaultLanguage = "en"; // return Task.FromResult(new ProviderCultureResult(defaultLanguage, defaultLanguage))!; //})); });
结果如下:
3、在Controller中可以通过DI注入IStringLocalizer<ResourceDemo> localizer
[ApiExplorerSettings(GroupName = "demo2")] [ApiController] [Route("[controller]")] public class ResourceController : Controller { private readonly IStringLocalizer<ResourceDemo> _localizer; public ResourceController(IStringLocalizer<ResourceDemo> localizer) { _localizer = localizer; } [HttpGet("resourcedemo")] public IActionResult ResourceDemo() { var value = _localizer.GetString("hello"); return new JsonResult(value); } }
Notes: 通常以上的知识点足以在常规的使用中如鱼得水,但有时候并不是通过HTTP请求这种方式获取资源,例如:单独请个进程或者线程执行某些操作,而这些操作所需的资源文件也是动态的,这种情况怎么办?
解答问题之前,不妨我们先看下NETCORE是如何使用资源文件的,我们在请求管道中UseRequestLocalization实则是调用NETCORE内部中间件,具体核心代码就是设置了当前线程/进程的CurrentUICulture,所以如果想在进程或者线程中改变资源文件,可以通过设置CurrentUICulture来完成。
[ApiExplorerSettings(GroupName = "demo2")] [ApiController] [Route("[controller]")] public class ResourceController : Controller { private readonly IStringLocalizer<ResourceDemo> _localizer; public ResourceController(IStringLocalizer<ResourceDemo> localizer) { _localizer = localizer; } [HttpGet("resourcedemo")] public IActionResult ResourceDemo() { var culture = Thread.CurrentThread.CurrentCulture; var value1 = _localizer.GetString("hello"); Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-us"); var value2 = _localizer.GetString("hello"); return new JsonResult($"Current thread culture: {culture.DisplayName}, value: {value1}; Set current thread UICulture(en-us), value: {value2}"); } }
Resource在ASP.NETCORE中很简单同样很实用!!!