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

雖然可以通過右上角的菜單切換成中文, 但是對于國内項目來說, 預設使用中文是很正常的需求.
本文介紹了如何實作預設語言的幾種方法, 希望能對ABP愛好者有所幫助, Let's begin!
前期準備
使用ABP CLI建立一個名為
AbpStudy
的ASP.NET MVC項目:
abp new AbpStudy
關于MVC的啟動模闆可以看文檔, 這裡就不贅述.
使用ABP版本的是目前最新的v3.0.2, 後續版本應該也适用
方法1: 通過服務設定
該方法參考了此回答, 謝謝@maliming.
- 編輯
工程下的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的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.
插入後的結果:
把方法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截圖:
再次檢視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
的清單, 預設清單中有三個值:
-
: 通過URL中的查詢字元串确定CultureQueryStringRequestCultureProvider
-
: 通過Cookie确定CultureCookieRequestCultureProvider
-
: 通過浏覽器發送的accept-header确定CultureAcceptLanguageHeaderRequestCultureProvider
這個清單的優先級為從上到下, 也就是說如果通過查詢字元串提供了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架構設定預設語言的方法就介紹到這, 示例工程放到GITHUB中.
Happy Coding!