Asp.Net Core 混合全球化与本地化支持

前言

       最近的新型冠状病毒流行让很多人主动在家隔离,希望疫情能快点消退。武汉加油,中国必胜!

       Asp.Net Core 提供了内置的网站国际化(全球化与本地化)支持,微软还内置了基于 resx 资源字符串的国际化服务组件。可以在入门教程中找到相关内容。

       但是内置实现方式有一个明显缺陷,resx 资源是要静态编译到程序集中的,无法在网站运行中临时编辑,灵活性较差。幸好我找到了一个基于数据库资源存储的组件,这个组件完美解决了 resx 资源不灵活的缺陷,经过适当的设置,可以在第一次查找资源时顺便创建数据库记录,而我们要做的就是访问一次相应的网页,让组件创建好记录,然后我们去编辑相应的翻译字段并刷新缓存即可。

       但是!又是但是,经过一段时间的使用,发现基于数据库的方式依然存在缺陷,开发中难免有需要删除并重建数据库,初始化环境。这时,之前辛辛苦苦编辑的翻译就会一起灰飞烟灭 (╯‵□′)╯︵┻━┻ 。而 resx 资源却完美避开了这个问题,这时我就在想,能不能让他们同时工作,兼顾灵活性与稳定性,鱼与熊掌兼得。

       经过一番摸索,终于得以成功,在此开贴记录分享。

正文

设置并启用国际化服务组件

       安装 Nuget 包 Localization.SqlLocalizer,这个包依赖 EF Core 进行数据库操作。然后在 Startup 的 ConfigureServices 方法中加入以下代码注册  EF Core 上下文:

1 services.AddDbContext<LocalizationModelContext>(options =>
2     {
3         options.UseSqlServer(connectionString);
4     },
5     ServiceLifetime.Singleton,
6     ServiceLifetime.Singleton);

       注册自制的混合国际化服务:

services.AddMixedLocalization(opts => { opts.ResourcesPath = "Resources"; }, options => options.UseSettings(true, false, true, true));

       注册请求本地化配置:

 1 services.Configure<RequestLocalizationOptions>(2     options =>3     {4         var cultures =  Configuration.GetSection("Internationalization").GetSection("Cultures")5         .Get<List<string>>()6         .Select(x => new CultureInfo(x)).ToList();7         var supportedCultures = cultures;8 9         var defaultRequestCulture = cultures.FirstOrDefault() ?? new CultureInfo("zh-CN");
10         options.DefaultRequestCulture = new RequestCulture(culture: defaultRequestCulture, uiCulture: defaultRequestCulture);
11         options.SupportedCultures = supportedCultures;
12         options.SupportedUICultures = supportedCultures;
13     });

       注册 MVC 本地化服务:

复制代码

1 services.AddMvc()
2     //注册视图本地化服务
3     .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix, opts => { opts.ResourcesPath = "Resources"; })
4     //注册数据注解本地化服务
5     .AddDataAnnotationsLocalization();

       在 appsettings.json 的根对象节点添加属性:

复制代码

"Internationalization": {"Cultures": ["zh-CN","en-US"]
}

       在某个控制器加入以下动作:

 1 public IActionResult SetLanguage(string lang)2 {3     var returnUrl = HttpContext.RequestReferer() ?? "/Home";4 5     Response.Cookies.Append(6         CookieRequestCultureProvider.DefaultCookieName,7         CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(lang)),8         new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }9     );
10 
11     return Redirect(returnUrl);
12 }

       准备一个页面调用这个动作切换语言。然后,大功告成!

       这个自制服务遵循以下规则:优先查找基于 resx 资源的翻译数据,如果找到则直接使用,如果没有找到,再去基于数据库的资源中查找,如果找到则正常使用,如果没有找到则按照对服务的配置决定是否在数据库中生成记录并使用。

自制混合国际化服务组件的实现

       本体:

       注册辅助扩展:

 

      原理简介

       服务组件利用了 DI 中可以为同一个服务类型注册多个实现类型的特性,并在构造方法中注入服务集合,便可以将注册的所有实现注入组件同时使用。要注意主控服务和工作服务不能注册为同一个服务类型,不然会导致循环依赖。内置的国际化框架已经指明了依赖 IStringLocalizerFatory ,必须将主控服务注册为 IStringLocalizerFatory,工作服只能注册为其他类型,不过依然要实现 IStringLocalizerFatory,所以最方便的办法就是定义一个新服务类型作为工作服务类型并继承 IStringLocalizerFatory。

       想直接体验效果的可以到文章底部访问我的 Github 下载项目并运行。

结语

       这个组件是在计划集成 IdentityServer4 管理面板时发现那个组件使用了 resx 的翻译,而我的现存项目已经使用了数据库翻译存储,两者又不相互兼容的情况下产生的想法。

       当时 Localization.SqlLocalizer 旧版本(2.0.4)还存在无法在视图本地化时正常创建数据库记录的问题,也是我调试修复了 bug 并向原作者提交了拉取请求,原作者也在合并了我的修复后发布了新版本。

       这次在集成 IdentityServer4 管理面板时又发现了 bug,正准备联系原作者看怎么处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/311806.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最大连续子数组和 动态规划_剑指Offer算法题 33:连续子数组的最大和

题目描述HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢&#xf…

数据结构---顺序查找和二分查找

数据结构—顺序查找和二分查找 原理&#xff1a;参考趣学数据结构 代码&#xff1a; #include<stdio.h> #include<stdlib.h> int n;//查找元素数组的长度 void seqCheckValue1(int* a) {//顺序查找1,有越界判断int v a[0];for (int i 1; i < n; i) {if(a[i…

git上托管的代码如何部署在阿里云上_居然仅用浏览器搞定Spring Boot应用的开发与部署...

最近有幸试用了一下阿里云的一个新产品&#xff1a;云开发平台&#xff0c;体验一把全新的开发模式&#xff01;虽然中间也碰到了一些问题&#xff0c;但整体的体验透露着未来感&#xff0c;因为整个过程都不需要使用我们最常用的IDEA&#xff0c;仅依靠浏览器就把一个Spring B…

Kubernetes 与 Helm:使用同一个 Chart 部署多个应用

k8s 集群搭建好了&#xff0c;准备将 docker swarm 上的应用都迁移到 k8s 上&#xff0c;但需要一个一个应用写 yaml 配置文件&#xff0c;不仅要编写 deployment.yaml 还要编写 service.yaml &#xff0c;而很多应用的配置是差不多的&#xff0c;这个繁琐工作让人有些望而却步…

数据结构---BF字符串模式匹配

数据结构—BF字符串模式匹配 原理&#xff1a;参考趣学数据结构 代码&#xff1a; #include<stdio.h> #include<stdlib.h> int BF(char * S, char* T,int pos,int n,int m) {//暴力算法求解子串T在S中第一次出现的位置int i pos, j 0;while (i < n &&a…

windows系统如何cmake_Windows操作系统如何快速增加分区?建议收藏

现在新买的电脑大都是出厂单分区的设置&#xff0c;也就是只有系盘C&#xff0c;没有D、E之类。于是也问过厂商的工作人员&#xff0c;得到的答复是恢复备份的机制已经十分完善&#xff0c;保证用户使用安全毫无问题。不过&#xff0c;相信小伙伴们和我一样&#xff0c;内心还是…

大白技术控 | Windows10X 模拟器简单上手体验

点击蓝字“大白技术控”关注我哟加个“星标★”&#xff0c;每日 19:30&#xff0c;好文必达&#xff01;前言Windows10X 和 Windows10 有什么区别&#xff1f;当这个问题摆在我面前的时候&#xff0c;我就脱口而出&#xff1a;区别&#xff1f;双屏了呗&#xff01;这个答案有…

word List 21

word List 21 如果存在什么问题&#xff0c;欢迎批评指正&#xff01;谢谢&#xff01;

Asp.Net Core Identity 骚断腿的究极魔改实体类

前言默认的 Identity 实体类型在大多数时候已经基本够用&#xff0c;很多时候也只是稍微在 IdentityUser 类中增加一些自定义数据字段&#xff0c;比如头像。这次&#xff0c;我要向园友隆重介绍我魔改之后的 Identity 实体类&#xff0c;能支持一些特别风骚的操作。当然也完全…

[蓝桥杯2015决赛]四阶幻方

题目描述 把1~16的数字填入4x4的方格中&#xff0c;使得行、列以及两个对角线的和都相等&#xff0c;满足这样的特征时称为&#xff1a;四阶幻方。 四阶幻方可能有很多方案。如果固定左上角为1&#xff0c;请计算一共有多少种方案。 比如&#xff1a; 1 2 15 16 12 14 3 5 13 7…

数据结构---模式匹配

数据结构—模式匹配 原理&#xff1a;参考趣学数据结构 代码&#xff1a; #include<stdio.h> #include<stdlib.h> #define N 100 int next[N]; void getNext(char *T,int *next,int m) {//求解当前字符前面的最大公共前缀和后缀int j 1,k0;next[j] 0;//从1开始…

CKEditor 4编辑器已与Vue.js集成

虽然 CKEditor 4 不是目前主要维护的分支&#xff0c;不过官方并没有让它落后于潮流。近日&#xff0c;CKEditor 团队发布了与 Vue.js 框架原生集成的 CKEditor 4。这就意味着&#xff0c;开发者可以通过<ckeditor />标签以 Vue.js 组件的形式使用 CKEditor 4 &#xff0…

[蓝桥杯2016初赛]卡片换位-bfs

题目描述 你玩过华容道的游戏吗&#xff1f;这是个类似的&#xff0c;但更简单的游戏。看下面 3 x 2 的格子 在其中放5张牌&#xff0c;其中A代表关羽&#xff0c;B代表张飞&#xff0c;* 代表士兵。还有一个格子是空着的。 你可以把一张牌移动到相邻的空格中去(对角不算相邻…

数据结构---KMP模式匹配病毒感染人的DNA检测

数据结构—KMP模式匹配病毒感染人的DNA检测 原理&#xff1a;参考趣学数据结构 代码&#xff1a; #include<stdio.h> #include<stdlib.h> #define N 100 int next[N]; void getNext(char *T, int *next, int m) {//求解当前字符前面的最大公共前缀和后缀int j …

推荐一个很棒的开源工作流elsa-core

开源项目orchard主要开发人员Sipke Schoorstra 开源了一个netcore 工作流项目&#xff0c;地址&#xff1a;https://github.com/elsa-workflows/elsa-core&#xff0c;最新版本1.2&#xff0c;正在开发2.0版本 。Spike 是参照Orchard Core的工作流引擎的原理&#xff0c;将其转…

WTM系列视频教程:MVVM

WTM系列视频教程第三章&#xff1a;MVVM文字摘要&#xff1a;“要讲MVVM模式&#xff0c;我们先来讲一下传统的MVC模式&#xff0c;要讲MVC模式&#xff0c;我们先来讲一下没有模式。。。”“为了演示没有模式&#xff0c;咱们整个项目就保留一个Program.cs文件&#xff0c;不使…

word List 22

word List 22 如果存在什么问题&#xff0c;欢迎批评指正&#xff01;谢谢&#xff01;

[蓝桥杯]波动数列

题目描述 观察这个数列&#xff1a;1 3 0 2 -1 1 -2 …这个数列中后一项总是比前一项增加2或者减少3。 栋栋对这种数列很好奇&#xff0c;他想知道长度为 n 和为 s 而且后一项总是比前一项增加a或者减少b的整数数列可能有多少种呢&#xff1f; 输入 输入的第一行包含四个整数 n…

ASP.NET 开源导入导出库Magicodes.IE Docker中使用

更新历史2019.02.13【Nuget】版本更新到2.0.2【导入】修复单列导入的Bug&#xff0c;单元测试“OneColumnImporter_Test”。问题见&#xff08;https://github.com/dotnetcore/Magicodes.IE/issues/35&#xff09;。【导出】修复导出HTML、Pdf、Word时&#xff0c;模板在某些情…

python爬取评论_python 爬取马蜂窝景点翻页文字评论的实现

使用Chrome、python3.7、requests库和VSCode进行爬取马蜂窝黄鹤楼的文字评论(http://www.mafengwo.cn/poi/5426285.html)。 首先&#xff0c;我们复制一段评论&#xff0c;查看网页源代码&#xff0c;按CtrlF查找&#xff0c;发现没有找到评论&#xff0c;说明评论内容不在http…