实例理解ASP.NET Core 中的国际化支持

posted at 2023.12.14 14:47 by 风信子

众多知名品牌的网站中,经常可以见到切换页面语言的功能,浏览者可以选择最适合自己的语言浏览页面内容。毫无疑问,为网站提供多种语言,页面内容的国际化,大大扩展了浏览者范围,提升了用户体验。

为了更好地理解下面的内容,我们先来了解一下行业内通用的名词术语: 

Ø  Globalization (G11N):全球化,即使应用支持不同语言和区域的过程。

Ø  Localization (L10N):本地化,即针对特定语言和区域自定义全球化应用的过程。

Ø  Internationalization (I18N)国际化,又称为多语言,包含了全球化和本地化。国际化常缩写为“I18N”。 缩写采用第一个和最后一个字母以及它们之间的字母数,因此 18 代表第一个字母“I”和最后一个“N”之间的字母数。 这同样适用于全球化 (G11N) 和本地化 (L10N)

Ø  Culture区域性,即一种语言文化或区域。

Ø  Specific Culture: 特定区域性,即具有指定语言和区域的区域性。

Ø  语言和国家/地区代码 RFC 4646 是一个与语言相关的 ISO 639 双小写字母的区域性代码和一个与国家/地区相关的 ISO 3166 双大写字母子区域性代码的组合。格式为 <language code>-<country/region code>,其中 <language code> 标识语言,<country/region code> 标识子区域性。 例如,es-CL表示西班牙语(智利),en-US 表示英语(美国),而 en-AU 表示英语(澳大利亚)。

Ø  本地化器 ASP.NET Core 提供了多种本地化工具:IStringLocalizer IStringLocalizerFactory IHtmlLocalizer IViewLocalizer

笔者的GuangBu Photos网站应用了ASP.NET Core 中的国际化支持,主要是采用以编程方式设置国际性。

下面介绍该网站的设置:       

一、首先在 Startup  ConfigureServices 中添加 AddLocalization  AddViewLocalization 以及配置 RequestLocalizationOptions

public void ConfigureServices(IServiceCollection services)
{
services.AddLocalization(options =>options.ResourcesPath = "Resources");
services.AddMvc()
        .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix); 
services.Configure<RequestLocalizationOptions>(
opts =>
        {
             var supportedCultures = new List<CultureInfo>
            {
new CultureInfo("en-US") 
new CultureInfo("zh-CN")
            };
opts.SupportedCultures = supportedCultures;
opts.SupportedUICultures = supportedCultures;
        });
} 

Startup  Configure() 方法中应用RequestLocalizationOptions  

Var  requestLocalizationOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>().Value;
app.UseRequestLocalization(requestLocalizationOptions);

  二、接着在网站中创建 Resources 文件夹,在其中分别添加 Views.Shared._Layout.en-Us.resxViews.Shared._Layout.zh-CN.resx 文件,并添加对应的字段,如:

        1Views.Shared._Layout.en-Us.resx

        2Views.Shared._Layout.zh-CN.resx

需要注意的地方:千万不要添加不带语言名称Views.Shared._Layout.en-Us.resx ,不然添加代码语言名称的 .resx 文件时会遇到 "Custom tool ResXFileCodeGenerator failed to produce an output for input file ... but did not log a specific error." 疑问。

  三、在控制器部分的代码如下:

WelcomeController.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
… …
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.Localization;
 
namespace Photos.Controllers
{
  [AllowAnonymous]
    public class WelcomeController : Controller
    {
        private readonly IRepository<Student, int> _studentRepository;
        private readonly IStringLocalizer<Photos.Resources.SharedResource> _localizer; 
        public WelcomeController(IRepository<Student, int> studentRepository, IStringLocalizer<Photos.Resources.SharedResource> localizer)
        {
            _studentRepository = studentRepository;
            _localizer = localizer;
        }
        [HttpPost]
        public IActionResult SetLanguage(string culture, string returnUrl)
        {
            Response.Cookies.Append(
                CookieRequestCultureProvider.DefaultCookieName,
                CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
                new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
            );
            return LocalRedirect(returnUrl);
        }
}

  四、表现层修改了以下页面:

      _Layout.cshtml嵌入部件页_SelectLanguagePartial.cshtml

    <div class="card-footer text-center">
        <div class="row col-4"> 
            <div class=" text-right">
                @await Html.PartialAsync("_SelectLanguagePartial")
            </div>
        </div> 
        <class="card-link"href="~/welcome/license"> @Localizer["License"]</a>
        <class="card-link"href="~/welcome/privacy"> @Localizer["Privacy"]</a>
        <class="card-link"href="~/welcome/terms"> @Localizer["Terms"]</a>
        <br/>
  </div>

_SelectLanguagePartial.cshtml 文件允许你从支持的区域性列表中选择区域性:

@using Microsoft.AspNetCore.Builder
@using Microsoft.AspNetCore.Http.Features
@using Microsoft.AspNetCore.Localization
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Options
 
@inject IViewLocalizer Localizer
@inject IOptions<RequestLocalizationOptions> LocOptions
 
@{
    var requestCulture = Context.Features.Get<IRequestCultureFeature>();
    var cultureItems = LocOptions.Value.SupportedUICultures
        .Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName })
        .ToList();
    var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}";
}
 
<div title="@Localizer["Request culture provider:"] @requestCulture?.Provider?.GetType().Name">
    <form id="selectLanguage"asp-controller="Welcome"
          asp-action="SetLanguage"asp-route-returnUrl="@returnUrl"
          method="post"class="form-horizontal"role="form">
        <label asp-for="@requestCulture.RequestCulture.UICulture.Name">
            @Localizer["Language:"]
        </label>
        <select name="culture"
                onchange="this.form.submit();"
                asp-for="@requestCulture.RequestCulture.UICulture.Name"asp-items="cultureItems">
        </select> 
    </form>
</div> 

这时运行 ASP.NET Core 站点,就会根据culture 参数、或者.AspNetCore.Culture Cookie 值显示对应语言的文字: 

Tags: , , , ,

IT技术

Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading