asp.net core 实现支持多语言

asp.net core 实现支持多语言

Intro

最近有一个外国友人通过邮件联系我,想用我的活动室预约,但是还没支持多语言,基本上都是写死的中文,所以最近想支持一下更多语言,于是有了多语言方面的一些实践

国际化/本地化介绍

国际化(Globalization)和本地化(Localization)是要实现的多语言支持的基础

Globalization is the process of designing and developing applications that function for multiple cultures.

Localization is the process of customizing your application for a given culture and locale.

国际化是要支持处理多种文化,而本地化是要根据某一个文化和区域的来展示相应的处理。

更多关于国际化与本地化的不同可以参考 Stack Overflow 上的讨论 https://stackoverflow.com/questions/2074869/globalization-vs-localization

Localization In Asp.NET Core

微软官方的 Localization 的实现是基于资源文件实现的 (*.resx),我们也可以扩展支持更多方式,如 JSON/数据库 都是可以的,社区已经有实现的示例,只要是可以提供一个文本源的都是可以的,我们先使用默认的基于资源文件的,下一篇再讲一个自定义实现一个 Localization Provider。

.NET Core Localization 的 核心是 IStringLocalizer,asp.net core 里扩展定义了 IViewLocalizerIHtmlLocalizerIViewLocalizerIHtmlLocalizer 主要是为了处理包含 html 的资源,他们不会对资源进行 html encode,相当于 @Html.Raw 的效果,而 IStringLocalizer 则会被 html encode,除此之外 IViewLocalizer 还会根据当前视图的路径寻找资源文件

来看一个示例:

Razor 页面

浏览器效果:

查看网页源代码:

实际案例

服务注册

注册 Localization 相关服务:

var supportedCultures = new[]
{
    new CultureInfo("zh"),
    new CultureInfo("en"),
};
services.Configure<RequestLocalizationOptions>(options =>
{
    options.DefaultRequestCulture = new RequestCulture("zh");
    // Formatting numbers, dates, etc.
    options.SupportedCultures = supportedCultures;
    // UI strings that we have localized.
    options.SupportedUICultures = supportedCultures;
});
services.AddLocalization(options => options.ResourcesPath = Configuration.GetAppSetting("ResourcesPath"));

配置视图 Localization(根据需要如果是 WebAPI 就不需要了)

services.AddControllersWithViews()
   .AddNewtonsoftJson(options =>
   {
       options.SerializerSettings.ContractResolver = new DefaultContractResolver();
       options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc; // 设置时区为 UTC
       options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
       options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
   })
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix,
                         opts => { opts.ResourcesPath = Configuration.GetAppSetting("ResourcesPath"); })
    .AddDataAnnotationsLocalization()
    .SetCompatibilityVersion(CompatibilityVersion.Latest);

中间件配置:

app.UseRequestLocalization();

逻辑代码中使用示例:

IStringLocalizerIHtmlLocalizer /IViewLocalizer 都可以直接从依赖注入服务中获取,IStringLocalizerIHtmlLocalizer 推荐使用强类型的方式,也就是下面示例的使用方式,使用方式和 ILogger 类似

public async Task<ActionResult> MakeReservation(
    [FromBody]ReservationViewModel model,
    [FromHeader]string captcha,
    [FromHeader]string captchaType,
    [FromServices]IStringLocalizer<HomeController> localizer)
{
    var result = new ResultModel<bool>();
    var isCodeValid = await HttpContext.RequestServices.GetService<CaptchaVerifyHelper>()
        .ValidateVerifyCodeAsync(captchaType, captcha);
    if (!isCodeValid)
    {
        result.Status = ResultStatus.RequestError;
        result.ErrorMsg = localizer["InvalidCaptchaInfo"];
        return Json(result);
    }

在视图中使用示例:

localizer["data"] 返回的是一个 LocalizedString,实现了隐式转换为 string, 有的时候可能需要强制转一下string, 或者使用 Value 属性

@inject IViewLocalizer viewLocalizer
viewLocalizer["About"]

@Html.ActionLink((string)viewLocalizer["About"], "About", "Home")
@Html.ActionLink(viewLocalizer["About"].Value, "About", "Home")

资源文件配置:

资源文件的配置和文件的结构类似,下面是一个示例

准备的来说是和类型的 FullName 有关系,一般的项目名称就是程序集名称,就是根命名空间,文件名称就是类型名称,所以一般情况下资源文件的位置和类型的位置是一致的,但是如果文件和类型名称不符合,那就要按照类型的 FullName 来找,视图也是类似的,如果根命名空间不是程序集名称,也是可以配置的具体的参考文档

Controllers.HomeController => Controllers/HomeController.zh.resx/Controllers/HomeController.en.resx

Resource name Dot or path naming
Resources/Controllers.HomeController.fr.resx Dot
Resources/Controllers/HomeController.fr.resx Path
  • Resources/Views/Home/About.fr.resx
  • Resources/Views.Home.About.fr.resx

实际项目中的资源文件示例:

实际访问效果:https://reservation.weihanli.xyz/

默认的中文界面:

英文界面:

只是做了几个前台的示例,还有很多地方没改

Docker 部署

现在的项目是基于 docker + k8s 部署的,所以支持 docker 部署很重要

要支持多语言,需要安装 ICU 相关的包,(这个可不是 996.icu 的 icu 哈,如果不装真的有可能导致 996.icu)

RUN apk add --no-cache icu-libs # 安装 icu-libs
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT false # 配置 Globalization

完整的 dockerfile 可以参考:
https://github.com/dotnet/dotnet-docker/blob/cb7a9c35dacf6d34fcf7bab7995e60faef55f61f/samples/dotnetapp/Dockerfile.alpine-x64-globalization

More

.net core 的设计真的是很灵活,很优美,基于资源文件的本地化,感觉不太方便,使用资源文件的化可能就只能使用 VS 编辑了,虽然也是纯文本的,基于 xml 但是编辑起来不如界面看着编辑舒服,如果使用 json 之类的,就比较简单明了,编辑起来也比较方便,所以想把资源文件替换成 JSON 文件

下次分享一篇基于 JSON 的 Localization Provider 的实现

Reference

原文地址:https://www.cnblogs.com/weihanli/p/implement-localization-in-asp-net-core.html

时间: 2024-11-29 08:16:40

asp.net core 实现支持多语言的相关文章

使Asp.net Core同时支持输出Json/Xml

我们知道Asp.net Core是支持输出为Json格式的.同时也支持输出为xml格式.只要我们正确的配置.并在Request时指定正确的Accept,即可根据不同的Header来输出不同的格式. 前几天看Jessite4.0读其日志,又看到这段文字 所有连接加 .json 或 .xml 或增加 __ajax=json 参数,或增加 __ajax=xml 参数,则自动返回 json 或 xml 数据,而不返回视图 于是在想,我们能不能提供下Asp.net Core中这种功能.最笨的办法,当然是在

体验 ASP.NET Core 中的多语言支持(Localization)

首先在 Startup 的 ConfigureServices 中添加 AddLocalization 与 AddViewLocalization 以及配置 RequestLocalizationOptions (这里假设使用英文与中文): public void ConfigureServices(IServiceCollection services) { services.AddLocalization(options => options.ResourcesPath = "Reso

快速搭建CentOS+ASP.NET Core环境支持WebSocket

以前用python,go尝试在linux下做web服务,python没有强类型支持与高性能,go又没有很好的集成开发环境(还有强迫症的语法),回头看了几次.net,都没有时间尝试,现终于实现了这些想法,与大家分享.做web大项目,做工程,必须要有称手的工具帮我调试.测试.开发.工程化很重要,VS是一个称职好选手. 环境:CentOS 7.x,.net core 2 以下.net core 2安装操作为官方方法.如果你使用Docker,那么更简单了,只需要docker pull microsoft

使用ASP.NET Core支持GraphQL -- 较为原始的方法

GraphQL简介 下面是GraphQL的定义: GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时. GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具. GraphQL由Facebook开发,始于2012年,2015年公开. GraphQL牛逼之处是它可以让客户端精确的查询它们想要的,不附加额外的东西,这样的话就很容易让

说说ASP.Net Core 2.0中的Razor Page

随着.net core2.0的发布,我们可以创建2.0的web应用了.2.0中新东西的出现,会让我们忘记老的东西,他就是Razor Page.下面的这篇博客将会介绍ASP.Net Core 2.0中的Razor Page. 在ASP.Net Core 2.0新特点之一就是支持Razor Page.今天的Razor Page是ASP.Net Core MVC中的一个子集.ASP.Net Core MVC 支持Razor Page意味着Razor Page应用从技术上来说就是MVC应用,同时Razo

ASP.NET Core 中文文档 第四章 MVC(3.2)Razor 语法参考

原文:Razor Syntax Reference 作者:Taylor Mullen.Rick Anderson 翻译:刘怡(AlexLEWIS) 校对:何镇汐 什么是 Razor? Razor 是一种基于服务器端代码的可以转换为网页的标记语法.Razor 语法包括 Razor 标记.C# 和 HTML 组成.包含 Razor 的文件通常后缀名为 .cshtml . 渲染 HTML Razor 的默认语言是 HTML.从 Razor 渲染为 HTML 和直接一个 HTML 文件没啥区别,这种 R

在 Azure WebApps 中运行64位 Asp.net Core 应用

作为微软下一代的开源的跨平台的开发框架, Asp.net core 正在吸引越来越多的开发者基于其构建现代 web 应用. 目前, Azure App Service 也实现了对 asp.net core 的支持. 用户所开发的 ASP.NET Core Web 应用, 以与通常 Asp.net Web 应用同样的方式部署到云端后,便可以被顺利执行. 但是,目前 Azure App Service 尚只支持32位的 Asp.net Core 运行时,即用户的 Asp.net Core 应用在云端

asp.net core mvc Partial View 应用

asp.net Core MVC支持部分视图特性,当我们在不同的项目中共享一些网页时,部分视图是非常有用的.1.部分视图定义:      部分视图是在一个视图中嵌套另外一个视图.在父视图中通过调用子视图并将子视图的HTML呈现给父视图.像一般视图一样,部分视图使用.cshtml文件扩展名.2.什么时候使用部分视图:      部分视图是将大的视图分解成较小视图组件的一种有效的方法.能使视图元素可以重复使用.通常布局元素在_Layout.cshtml中指定.非布局的并且可以重复的内容可以封装成部分

[转]使用依赖关系注入在 ASP.NET Core 中编写干净代码

本文转自:http://blog.jobbole.com/101270/ 原文出处: Steve Smith ASP.NET Core 1.0 是 ASP.NET 的完全重新编写,这个新框架的主要目标之一就是更多的模块化设计.即,应用应该能够仅利用其所需的框架部分,方法是框架在它们请求时提供依赖关系.此外,使用 ASP.NET Core 构建应用的开发人员应该能够利用这一相同功能保持其应用松散耦合和模块化.借助 ASP.NET MVC,ASP.NET 团队极大地提高了框架的支持以便编写松散耦合代