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": "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
的列表, 默認列表中有三個值:
QueryStringRequestCultureProvider
: 通過URL中的查詢字符串確定CultureCookieRequestCultureProvider
: 通過Cookie確定CultureAcceptLanguageHeaderRequestCultureProvider
: 通過瀏覽器發送的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框架設置默認語言的方法就介紹到這, 示例工程放到GITHUB中.
Happy Coding!