zoukankan      html  css  js  c++  java
  • 设置ABP默认使用中文(更新ABP v3.0方法)

    ABP提供的启动模板, 默认使用是英文:

    https://img2018.cnblogs.com/blog/648050/201908/648050-20190830094940792-898787622.png

    虽然可以通过右上角的菜单切换成中文, 但是对于国内项目来说, 默认使用中文是很正常的需求.
    本文介绍了如何实现默认语言的几种方法, 希望能对ABP爱好者有所帮助, Let's begin!

    前期准备

    使用ABP CLI创建一个名为AbpStudy的ASP.NET MVC项目:

    abp new AbpStudy
    
    

    关于MVC的启动模板可以看文档, 这里就不赘述.

    使用ABP版本的是当前最新的v3.0.2, 后续版本应该也适用

    方法1: 通过服务设置

    该方法参考了此回答, 谢谢@maliming.

    1. 编辑AbpStudy.Web工程下的Startup.cs文件, 在Configure方法的开始增加一行代码:
            public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
            {
                app.ApplicationServices.GetService<ISettingDefinitionManager>().Get(LocalizationSettingNames.DefaultLanguage).DefaultValue = "zh-Hans";     // 默认使用中文
                app.InitializeApplication();
            }
    
    

    该方法首先获取了SettingDefinitionManager的服务实例, 然后调用Get方法获取了默认语言的SettingDefinition, 然后设置了默认值"zh-Hans", 即中文.

    运行, 就会发现默认语言已经变成中文了:

    https://img2018.cnblogs.com/blog/648050/201908/648050-20190830105853639-1668861586.png

    怎么样, 非常简单吧?

    关于ABP的Setting, 现在官方的文档还未写完. 等待官方文档完善后我会更新到文章里

    2019/11/9更新: 文档已上线 点击查看

    方法2: 通过数据设置

    虽然方法1非常简单, 但是因为是通过代码写死了默认语言, 如果想设置其他默认语言, 只能再次修改代码.

    既然默认语言是通过Setting设置的, 那么我们可不可以通过数据设置默认语言呢?答案是肯定的.

    ABP启动模板的数据库中有一个名为AbpSettings的表, 里面即是各种Setting的值.

    我们可以向其中增加一条默认语言的记录:

    INSERT INTO AbpSettings(Id, Name, Value, ProviderName)
    Values(newid(), 'Abp.Localization.DefaultLanguage', 'zh-Hans', 'Global')
    
    

    其中的Name的值即是方法1中LocalizationSettingNames.DefaultLanguage的值, 相当于默认语言Setting的一个Key.
    插入后的结果:

    https://img2018.cnblogs.com/blog/648050/201908/648050-20190830112907453-1063066096.png

    把方法1中我们增加的那行代码删除后, 再次运行确认默认语言仍然是中文.

    如果我们把记录中的"zh-Hans"改为"en", 重新运行后默认语言就会切换成英文了.

    方法3: 通过Seed设置

    方法3实际上是方法2的一个改进: 我们利用了ABP提供了Seed系统(即可通过代码初始化系统的一些数据), 这样我们在正式上线项目时, 不需要再额外执行SQL语句来执行数据初始化了.

    首先我们把AbpSettings表中我们手动插入的那条记录删除.

    然后在AbpStudy.Domain工程的Settings文件夹中增加一个名为AbpStudySettingDataSeedContributor的类, 用来为Setting设置初始化数据. 类代码如下:

        public class AbpStudySettingDataSeedContributor : IDataSeedContributor, ITransientDependency
        {
            private readonly IGuidGenerator _guidGenerator;
            private readonly ISettingRepository _settingRepository;
    
            public AbpStudySettingDataSeedContributor(IGuidGenerator guidGenerator, ISettingRepository settingRepository)
            {
                _settingRepository = settingRepository;
                _guidGenerator = guidGenerator;
            }
    
            public async Task SeedAsync(DataSeedContext context)
            {
                await _settingRepository.InsertAsync(new Setting(
                    _guidGenerator.Create(),
                    LocalizationSettingNames.DefaultLanguage,
                    "zh-Hans",
                    GlobalSettingValueProvider.ProviderName
                ));
            }
    
    

    该类注入GuidGenerator用来生成GUID, 和SettingRepository用来向AbpSettings表插入数据.

    SeedAsync方法中使用InsertAsync方法插入了默认语言的记录, 记录的值与方法2中SQL中是一致的.

    然后我们运行AbpStudy.DbMigrator工程, 这是启动模板附带的一个用来执行数据库迁移的一个工具, 它会扫描到我们刚写的AbpStudySettingDataSeedContributor类并调用它, 从而完成数据初始化.

    AbpStudy.DbMigrator工程有自己的数据库连接串, 定义在appsettings.json文件中, 别忘了将它修改成与Web工程中的一样.

    运行DbMigrator截图:

    https://img2018.cnblogs.com/blog/648050/201908/648050-20190830120321824-153860222.png

    再次查看AbpSettings表中的数据, 发现记录已经插入了, 与我们使用SQL语句插入的一样, 所以默认中文也同样可以生效.


    2020-07-04 更新开始

    方法4: 通过配置文件设置

    ABP中的Setting可通过配置文件(默认为appsetting.json)设置(见文档), 这应该是设置Setting值最简单的方式了. 实际上在ABP的默许启动模板中, 就通过这种方式设置了一些值: 打开 AbpStudy.Web工程下的appsetting.json文件, 你会发现以下内容:

    "Settings": {
        "Abp.Mailing.Smtp.Host": "127.0.0.1",
        "Abp.Mailing.Smtp.Port": "25",
        "Abp.Mailing.Smtp.UserName": "",
        "Abp.Mailing.Smtp.Password": "",
        "Abp.Mailing.Smtp.Domain": "",
        "Abp.Mailing.Smtp.EnableSsl": "false",
        "Abp.Mailing.Smtp.UseDefaultCredentials": "true",
        "Abp.Mailing.DefaultFromAddress": "noreply@abp.io",
        "Abp.Mailing.DefaultFromDisplayName": "ABP application"
    }
    

    在最后增加一行内容: "Abp.Localization.DefaultLanguage": "zh-Hans", 就样就可设置默认语言为中文.

    没有效果?

    但是有网友反映这样设置后, 在ABP3.0中默认语言还是英文, ABP的GIHUB上也有一些类似的ISSUE(#2775, #2469). 这又是什么原因呢?

    原因是浏览器发送的中文的accept-language的值与ABP值不匹配导致的:

    • 浏览器(如Chrome)的值为zh-CN
    • 而ABP的简体中文的值为zh-Hans

    解决的办法也很简单:

    修改AbpStudy.Web工程下的AbpStudyWebModule类中的OnApplicationInitialization方法, 找到app.UseAbpRequestLocalization(), 替换为下面的代码:

    app.UseAbpRequestLocalization(options =>
        {
            options.RequestCultureProviders.RemoveAll(provider => provider is AcceptLanguageHeaderRequestCultureProvider);
        }
    );
    

    这样修改后, ABP就会忽略浏览器发送的accept-language值, 从而使我们的默认设置生效. (别忘了清除浏览器的Cookie缓存)

    以下是一些技术细节, 不感兴趣可以不看:)

    ASP.NET Core的本地化机制中会维护一个RequestCultureProvider的列表, 默认列表中有三个值:

    1. QueryStringRequestCultureProvider : 通过URL中的查询字符串确定Culture
    2. CookieRequestCultureProvider : 通过Cookie确定Culture
    3. AcceptLanguageHeaderRequestCultureProvider : 通过浏览器发送的accept-header确定Culture

    这个列表的优先级为从上到下, 也就是说如果通过查询字符串提供了Culture, 那么剩下的Provider就不会有生效.

    而ABP的语言默认值, 只有列表中所有的Provider都未命中才会生效.

    你可以试一下通过在URL后加上?culture=zh-Hans, 这样会强制使用简体中文, 因为QueryString是优先级最高的

    同理, Cookie是第2高的, 所以上面让你清除浏览器Cookie, 以免影响默认值

    上面的解决方法的思路就是, 把第3个AcceptLanguageHeaderRequestCultureProvider从列表中删除了, 从而让默认语言值生效.

    更多细节请查看ASP.NET Core本地化文档

    2020-07-04 更新结束

    禁用其他语言

    如果你的项目不用考虑多语言, 那么右上角的语言切换菜单就显得有点多余了, 我们可以通过以下修改禁用其他语言:

    修改AbpStudy.Web工程下的AbpStudyWebModule类, 将ConfigureLocalizationServices方法中其他语言的options.Languages.Add(...)代码删除, 只保留中文的即可:

            private void ConfigureLocalizationServices()
            {
                Configure<AbpLocalizationOptions>(options =>
                {
                    options.Resources
                        .Get<AbpStudyResource>()
                        .AddBaseTypes(
                            typeof(AbpUiResource)
                        );
    
                    //options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština"));
                    //options.Languages.Add(new LanguageInfo("en", "en", "English"));
                    //options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
                    //options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe"));
                    options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
                });
            }
    
    

    再次运行, 发现右上角语言切换的菜单就不见了, 完美!

    https://img2018.cnblogs.com/blog/648050/201908/648050-20190830121111108-1711462586.png

    关于ABP框架设置默认语言的方法就介绍到这, 示例工程放到GITHUB中.
    Happy Coding!

  • 相关阅读:
    STL中队列queue的常见用法
    牛客网剑指offer第17题——树的子结构
    《剑指offer》网络大神所有习题题解
    牛客网剑指offer第4题——重建二叉树
    牛客网剑指offer第56题——删除链表中重复的节点
    图像处理中的求导问题
    hash_set和hash_map
    hashtable初步——一文初探哈希表
    数据结构-链表的那些事(下)(二)
    数据结构-链表的那些事(上)(一)
  • 原文地址:https://www.cnblogs.com/waku/p/11433242.html
Copyright © 2011-2022 走看看