天天看點

設定ABP預設使用中文(更新ABP v3.0方法)

ABP提供的啟動模闆, 預設使用是英文:

設定ABP預設使用中文(更新ABP v3.0方法)

雖然可以通過右上角的菜單切換成中文, 但是對于國内項目來說, 預設使用中文是很正常的需求.

本文介紹了如何實作預設語言的幾種方法, 希望能對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", 即中文.

運作, 就會發現預設語言已經變成中文了:

設定ABP預設使用中文(更新ABP v3.0方法)

怎麼樣, 非常簡單吧?

關于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.

插入後的結果:

設定ABP預設使用中文(更新ABP v3.0方法)

把方法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截圖:

設定ABP預設使用中文(更新ABP v3.0方法)

再次檢視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": "[email protected]",
    "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", "簡體中文"));
            });
        }

           

再次運作, 發現右上角語言切換的菜單就不見了, 完美!

設定ABP預設使用中文(更新ABP v3.0方法)

關于ABP架構設定預設語言的方法就介紹到這, 示例工程放到GITHUB中.

Happy Coding!