ASP.NET Core 3.1系列(10)——基于资源文件(*.resx)的国际化多语言实现方法

32 篇文章 42 订阅

1、前言

当软件需要在多个国家和地区使用时,对系统进行国际化多语言处理就成了顺理成章的事情。针对多语言场景,ASP.NET Core提供了一种基于资源文件(*.resx)的多语言实现方法,下面开始介绍。

2、初级方法实现多语言

Controller的方法中,我们经常需要输出一些有意义的文本信息对用户进行提示,下面代码演示了根据不同的id值输出不同的提示信息:

using Microsoft.AspNetCore.Mvc;

namespace App.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class HomeController : ControllerBase
    {
        [HttpGet]
        public ActionResult<string> Get(int id = 1)
        {
            if (id > 0)
            {
                return Ok("查询成功");
            }
            else if (id == 0)
            {
                return NotFound("查询不到数据");
            }
            else
            {
                return BadRequest("参数错误");
            }
        }
    }
}

对于咱们来说,看懂上面的提示信息根本不是问题。现在问题来了:该应用需要添加英文(en-US)支持,以便外国人理解。大多数人的第一想法肯定是根据不同的语言环境生成不同的提示信息,也就是最基础的if...else,其代码如下所示:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;

namespace App.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class HomeController : ControllerBase
    {
        private readonly IConfiguration configuration;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="configuration"></param>
        public HomeController(IConfiguration configuration)
        {
            this.configuration = configuration;
        }

        /// <summary>
        /// 获取提示信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<string> Get(int id = 1)
        {
            string language = configuration["DefaultLanguage"].ToString();
            if (id > 0)
            {
                if (language == "zh-CN")
                {
                    return Ok("查询成功");
                }
                else
                {
                    return Ok("Search successful");
                }
            }
            else if (id == 0)
            {
                if (language == "zh-CN")
                {
                    return NotFound("查询不到数据");
                }
                else
                {
                    return Ok("Can't find data");
                }
            }
            else
            {
                if (language == "zh-CN")
                {
                    return BadRequest("参数错误");
                }
                else
                {
                    return Ok("Parameter error");
                }
            }
        }
    }
}

上面的代码中注入了一个IConfiguration接口用来读取当前语言环境,然后根据语言环境输出对应的提示信息。虽然上面的方法实现了多语言,但相信你也应该看出来了,该方法毫无扩展性,如果后续还需要引入越南语、韩语、蒙古语等诸多语言,那么上面的代码将会是灾难性的。

3、使用资源文件实现多语言

3.1、添加资源文件

下面来看看如何利用资源文件(*.resx)实现多语言。首先创建一个Resources文件夹,然后在该文件夹中创建一个Controllers文件夹,添加两个资源文件,如下图所示:

  • HomeController.en-US.resx
  • HomeController.zh-CN.resx

在这里插入图片描述
我们可以在资源文件中添加一些测试文本数据,如下图所示:
在这里插入图片描述
在这里插入图片描述

3.2、添加多语言支持

Startup.cs文件中添加多语言模块的支持,代码如下:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Collections.Generic;
using System.Globalization;

namespace App
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            // 添加国际化支持
            services.AddLocalization(options =>
            {
                options.ResourcesPath = "Resources";
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            // 中英文支持
            var supportedCultures = new List<CultureInfo>
            {
                new CultureInfo("en-US"),
                new CultureInfo("zh-CN"),
            };
            app.UseRequestLocalization(new RequestLocalizationOptions
            {
                DefaultRequestCulture = new RequestCulture("zh-CN"),
                SupportedCultures = supportedCultures,
                SupportedUICultures = supportedCultures
            });

            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
            
        }
    }
}

3.3、注入IStringLocalizer接口

ASP.NET Core中主要使用IStringLocalizer读取多语言文本,只需要在控制器的构造函数中将其注入即可,其代码如下所示:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;

namespace App.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class HomeController : ControllerBase
    {
        private readonly IStringLocalizer<HomeController> localizer;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="localizer"></param>
        public HomeController(IStringLocalizer<HomeController> localizer)
        {
            this.localizer = localizer;
        }

        /// <summary>
        /// 获取多语言信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<string> Get()
        {
            return localizer.GetString("Hello").Value;
        }
    }
}

URL改为https://localhost:5001/api/Home/Get?ui-culture=zh-CN,运行结果如下图所示:
在这里插入图片描述
URL改为https://localhost:5001/api/Home/Get?ui-culture=en-US,运行结果如下图所示:
在这里插入图片描述
到此为止,基于资源文件的多语言就完成了。

4、设置语言文化提供器

ASP.NET Core的国际化多语言中间件默认支持3种语言文化提供器:

  • URL中的查询字符串
  • Cookie
  • Header请求头

4.1、URL中的查询字符串

上面代码虽然实现了多语言,但你可能会有一个疑问:IStringLocalizer是如何定位到对应语言的资源文件的?其实这是由ASP.NET Core中资源文件的命名约定决定的。

4.1.1、指定文件夹

首先看如下代码,这段代码表示到Resources文件夹中去找多语言资源文件。

services.AddLocalization(options =>
{
	options.ResourcesPath = "Resources";
});
4.1.2、指定控制器

接着是控制器中的多语言访问器IStringLocalizer,其泛型参数为HomeController,由于该控制器位于工程中的Controllers文件夹,因此这也就告诉程序到Resources文件夹下的Controllers文件夹中去寻找一个名称为HomeController的资源文件。

private readonly IStringLocalizer<HomeController> localizer;
4.1.3、指定语言环境

名称为HomeController的资源文件有两个,分别以zh-CN.resxen-US.resx结尾。如果URL中的ui-culture值为en-US,则读取HomeController.en-US.resx,反之则读取HomeController.zh-CN.resx

https://localhost:5001/api/Home/Get?ui-culture=en-US

4.2、Cookie设置多语言

如果不想在每个URL中添加ui-culture参数,那么也可以考虑使用Cookie的方式来实现多语言。在当前网页中添加一个Cookie,名称为.AspNetCore.Culture,值为c=zh-CN|uic=zh-CN,则运行结果如下图所示:
在这里插入图片描述

如果将.AspNetCore.Culture的值设置为c=zh-CN|uic=zh-CN,则运行结果如下图所示:
在这里插入图片描述

4.3、Header请求头设置多语言

ASP.NET Core也支持在请求头中指定语言文化,这里以Edge浏览器为例。当前浏览器的默认语言为简体中文,因此请求头中的accept-language值为zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,如下图所示:
在这里插入图片描述
此时程序会读取HomeController.zh-CN.resx,因此输出结果为中文,如下图所示:
在这里插入图片描述
现在我们将Edge浏览器改为英文模式,如下图所示:
在这里插入图片描述
再次运行程序,发现accept-language值更改了,如下图所示:
在这里插入图片描述
此时程序会读取HomeController.en-US.resx,因此输出结果为英文,如下图所示:
在这里插入图片描述

5、结语

本文主要介绍了ASP.NET Core中基于资源文件的多语言实现方法。这里需要注意:上面只是为了演示,因此Cookie是我手动添加进去的,实际开发过程中还是需要使用HttpContext操作Cookie

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
*.resources文件是一种特殊的文件格式,用来存储和管理软件程序的本地化源。当一个软件需要在不同的语言环境下运行时,就需要使用*.resources文件来存储不同语言的翻译文本、图像、声音等源。 编辑*.resources文件可以通过多种方式进行。一种常用的方式是使用源编辑器软件,比如Visual Studio的源编辑器。通过打开*.resx文件,我们可以在源编辑器中看到不同的语言源,并对其进行编辑、添加和删除操作。例如,我们可以修改其中的文本,替换为其他语言的翻译文本;或者修改其中的图片源,更新为不同语言版本的图片。 另一种方式是手动编辑*.resx文件,这需要一定的编程知识。通过打开*.resx文件,我们可以使用文本编辑器对其中的XML代码进行修改。例如,在<value>标签中修改文本源的值,或者通过添加、删除<data>标签来修改其他源。 在编辑*.resources文件时,需要注意以下几点。首先,应该确保编辑的是正确的文件,不要修改其他文件;其次,应该遵循对应的源命名规范,确保编辑过的源能够在程序中正确被引用;最后,应该在编辑前备份原始文件,以防止编辑错误导致的数据丢失。 通过编辑*.resources文件,我们可以实现软件的多语言本地化,使得软件能够在不同语言环境下更好地运行,并提供更好的用户体验。无论是使用源编辑器软件还是手动编辑,正确的编辑方式能够保证源的准确性和完整性,从而提高软件的质量和适应性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值