前情提要: MVC-多國語系設定方法
(簡單描述開發環境)
使用環境: ASP.Net Core 2.X
開發工具: VSCode
範例網址: 多語範例Github 已經進行本次的更新了
本篇會說明以上方設定的方法後,後續會遇到的問題。
1. Cshtml中使用Asp屬性自動生成URL
修改在Home/About頁面
若需要以REST-like的方式取資料的話,加入語系的時候會出現問題1
2
3
4
5
6
7[ ]
public IActionResult About(int? year, int? month)
{
ViewData["param"] = year + "/" + month;
return View();
}
若在Cshtml中使用Asp屬性跳轉頁面的話會有以下情況:1
2<li><a asp-route-culture="zh">zh</a></li>
<li><a asp-route-culture="en">en</a></li>
會以莫名的方式自動生成這樣的URL,到前端后會有這種情況:1
2<li><a href="/Home/About?culture=zh">zh</a></li>
<li><a href="/Home/About?culture=en">en</a></li>
**需要多了解一下Asp的taghelper的生成原理,以及Route的邏輯
個人推測為是因為
[HttpGet("[controller]/[action]/{year?}/{month?}")]
這邊修改了Route的邏輯,所以會出現生成不一樣的URL邏輯
目前稍微研究出使用startup.cs
檔案中的maproute部分去做對照。
這方法是目前想到的方法,但是又覺得有點不合適。。。
(經過測試,自動生成URL時偶爾會生產錯誤的url,所以目前就先不理會了。。。)1
2
3
4routes.MapRoute(
name: "About",
template: "About/{action=Index}/{year?}/{month?}",
defaults: new {controller="About", culture = "zh" });
2. URL中語系欄位沒有進行限制
在多語範例Github中,設定了由url決定語系。
但是若在url的語系的部分中胡亂輸入,僅僅會自動fallback到預設的語系,但是正常來說應該進行限制的。
例如進入/fake-culture/Home/About
,則會以zh
為語系顯示。
解決方法:(在startup.cs
中)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}",
defaults: new { culture = "zh" });//這部分不需要加入contraints,因為已經寫死是zh了
routes.MapMiddlewareRoute("{culture=zh}/{*mvcRoute}", subApp =>
{
subApp.UseRequestLocalization(localizationOptions.Value);
subApp.UseMvc(mvcRoutes =>
{
mvcRoutes.MapRoute(
name: "default",
template: "{culture}/{controller}/{action}/{id?}",
defaults: new { culture = "zh", Controller = "home", action = "index" },
constraints: new { Culture = @"(zh)|(en)" }); //加入這行即可
//正規表達式可以match的話則會正常進入相關頁面,若沒有match的話,則會變為404
});
});
});
3. 程式Namespace與Assembly的問題(非語系問題)
這部分是在做範例程式時遇到的陷阱,會導致多語套件設定錯誤的namaspace。
這部分牽涉的範圍較廣,並非只有語系套件會出現問題。
由於專案命名為core-localization
,因為” - “是程式碼的運算子,所以在程式中會自動將namespace改編為:core_localization
。
結果就發現多語無論如何都抓不到對的語系檔,因此讓我鬱悶了一段時間。
在某次機緣之下,發現了下面的東西:(VSCode Debugger)
因為專案預設的namespace是core-localization
與程式碼內的namespace core_localization
不一致,所以自動尋找資源檔時會找尋到這個namespace core-localization.Resources.core_localization.X.X.X
。
所以必須在csproj裡面設定預設的namespace以及assembly的名字:
***其實這個解決方法在StackOverflow上已經看到過多次了,因為不知道是DefaultNamespace的問題,所以一直都沒有採用這個解決方法
在設定好後就可以抓到對的namespace: core_localization.Resources.X.X.X
後記
表示一開始只是工作上需要設定多語,然後再來設定URL語系,發現這個設定方法對於Google的SEO是有幫助的。
然後在寫的途中找到了限制URL語系的方法,這又能反饋回原本的專案。
再來在寫部落格時無法達成多語功能(詳情在第三部分),因此了解到了namespace的問題,學習到了多一個知識。
寫blog的好處就這樣漸漸凸顯出來了!!
知識鏈接
微軟官方路徑約束文檔
ASP.NET Core Localization Deep Dive
John Wu-多國語言教學