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 });
resource configuration
1 var requestLocalizationOptions = app.Services.GetService<IOptions<RequestLocalizationOptions>>();
2 app.UseRequestLocalization(requestLocalizationOptions!.Value);
configuration pipeline

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));
    }
}
MyCustomRequestProvider

       更改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))!;
    //}));
});
ConfigureService

        结果如下:

 

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);
        }
    }
DemoController

 

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}");
        }
    }
CurrentUICulture

 

Resource在ASP.NETCORE中很简单同样很实用!!!

 

posted @ 2023-03-04 09:37  云霄宇霁  阅读(146)  评论(0编辑  收藏  举报