[ASP.NET MVC] 多國語系切換 – 使用資料庫管理與兼容 JavaScript 顯示

[ASP.NET MVC] 多國語系切換 – 使用資料庫管理與兼容 JavaScript 顯示

網站的多國語系切換是走向國際發展的第一步,本篇文章將會教你如何使用 ASP.NET MVC 的多國語系切換功能,教學內容是接近實務應用的作法,使用資料庫管理多國語言,以及讓 JavaScript 檔案也可以顯示不同語系。

在官方的教學中是使用 Resources 儲存多國語系,當有多個語系時就要同時編寫多個檔案。
我的設計方式是將多國語系存放在資料庫裡面統一管理,再利用程式將資料庫裡面語系輸出至 Resources 裡面,與官方教學模式有些不同,有興趣的朋友可以多學一種設計模式。

之前寫多國語系時,*.cshtml 上文字可以使用資源檔的值,可是 JavaScript 的 *.js 檔案就無法使用,所以我另外提供一種讓 JavaScript 檔案也可以顯示多語系的方法給各位參考。

在最後提供此範例的原始程式碼下載,有需要的朋友可以自行下載來執行。

建立專案

開啟 Visual Studio 2022,建立新專案為「ASP.NET Web 應用程式 (.NET Framework)」。

開啟 Visual Studio 2022,建立新專案為「ASP.NET Web 應用程式 (.NET Framework)」

輸入專案名稱、位置之後,選擇「MVC」範本,就可以建立專案。

加入全域資源檔

全域資源檔是存放多語系的文件,主要是存放語系對照表,不同語系就要建立一個檔案。
在專案上按右鍵選「加入 > 加入 ASP.NET 資料夾 > App_GlobalResources(R)」。

在專案上按右鍵選「加入 > 加入 ASP.NET 資料夾 > App_GlobalResources(R)」

接著在出現的「App_GlobalResources」再按右鍵「加入 > 資源檔」。

接著在出現的「App_GlobalResources」再按右鍵「加入 > 資源檔」

第 1 個要建立的主要語系,我建議檔名直接用 “Language.resx” 就可以了。

我建議檔名直接用 “Language.resx” 就可以了

接著建立第 2 個語系檔,我這裡用英文來示範,一樣在「App_GlobalResources」再按右鍵「加入 > 資源檔」,檔名可用 “Language.en-US.resx”。

檔名可用 “Language.en-US.resx”

如果有很多語系,就預先將文件建立起來,檔名規則預設語系是 “Language.resx”,其他語系就用 “Language.{語系-國家}.resx” 來建立。

建立資料表

這裡用 SQL Server 做教學資料庫,尚未安裝 SQL Server 的話,可參考這篇文章: Windows Server 如何安裝 SQL Server 2019 免費開發版

開啟資料庫,我已建好教學資料庫 “Teach”,繼續建立新 Table,以下是新 Table Schema。

會建立資料表來管理語系只是一種習慣的應用,方便管理與維護,以官方建議的方法是寫在資源檔裡面,兩種方法都行,取決於維護方便就好。
而我使用資料庫還是會將資料庫的內容寫入資源檔裡面,所以兩者結果是一樣的,只是多了一道步驟而已。

寫入測試資料

用以下一些測試資料來示範。

關於 Key 欄位的值用中文或英文都行,差別是取用時的 Key 不同,而 Key 欄位的值要單純一點,不可放入符號或語法。
而 Key 與預設語言會分開欄位,這與在 Resources 建立對照表時是相同,Resources 本身是 Key/Value 對照表,這裡對預設語系也有 Key/Value 的對照,也就是 Lang_Key 與 Lang_zhTW 的對照欄位。

讀取資料庫寫入資源檔

這裡會寫一個方法將資料庫裡面的值,分別寫入不同的語系檔裡面,當我們有修改資料庫內的值時,就可以呼叫這個方法。
這裡我示範時就先寫在 HomeController 的 UpdateLang() 動作裡面,方便程式呼叫。

這裡查詢資料庫的方法我使用了 Dapper 套件,Dapper 是 ORM 的一種解決方案,也可以使用一般 ADO.NET 或是 EF 來查詢資料庫,只要查詢出來的資料寫入資源檔裡面就行了。

關於更多 Dapper 的語法,可參考「黑暗執行緒」的文章教學

資料庫連線設定

資料庫連線設定放在 Web.config 裡面,可以加入以下語法設定連線字串。

加入 Dapper 套件

開啟專案的「參考 > 管理 NuGet 套件」。

開啟專案的「參考 > 管理 NuGet 套件」

搜尋 “Dapper” 找到最新的「Dapper」套件安裝。

搜尋 “Dapper” 找到最新的「Dapper」套件安裝

安裝完成後,就可在引用錯誤的語法上加入 using Dapper; 語法。

安裝完成後,就可在引用錯誤的語法上加入 using Dapper; 語法

測試更新語系資源檔

這裡完成了第一個方法,目的是將資料庫語系寫入資源檔裡面,執行專案後,只要網址執行 /Home/UpdateLang 就可以執行方法。

更新之後再打開「Language.resx」可以看到預設語系已經寫入了。

更新之後再打開「Language.resx」可以看到預設語系已經寫入了

英文語系檔「Language.en-US.resx」也有寫入值。

英文語系檔「Language.en-US.resx」也有寫入值

未來資料庫有新增值或刪除值的時候,只要執行這個方法,都可以同步更新到資源檔裡面。

顯示目前語系

這裡要講解的是顯示目前使用者語系,會從 Cookie 裡面取語系名稱,如果 Cookie 裡面沒有設定的話,則顯示預設語系。

建立專案底層類別

取得多語系是每一個 Controller 在呼叫前都會執行的動作,這裡我建立一個新類別 “ProjectBase” 來繼承 Controller,同時讓所有 Controller 繼承此類別。

在「Controllers 按右鍵 > 加入 > 類別」,加入一個新類別。

在「Controllers 按右鍵 > 加入 > 類別」,加入一個新類別

新類別名稱為 “ProjectBase”。

新類別名稱為 “ProjectBase”

在新建立的 “ProjectBase” 類別裡面,我們直接繼承 Controller。
在 ProjectBase 後面增加 : Controller

在 ProjectBase 後面增加 : Controller

編寫 OnActionExecuting 事件

OnActionExecuting 事件是 ASP.NET MVC 生命週期中的一個事件,順序排在執行 Controller 之前,所以我們先在 OnActionExecuting 事件裡面完成語系讀取,再顯示出來。

OnActionExecuting 事件方法就寫入剛剛新增的 ProjectBase 類別裡面。

HomeController 繼承 ProjectBase

剛剛新增的 ProjectBase 類別就要讓所有的專案 Controller 繼承使用。
打開 \Controllers\HomeController.cs 將原本的 public class HomeController : Controller 改成 public class HomeController : ProjectBase

HomeController 繼承 ProjectBase

修改 View 頁面

這裡我用 \Views\Home\Index.cshtml 做為前端示範,先清空 \Views\Home\Index.cshtml 裡面原本的語法,然後加入以下語法。

執行專案後,就會顯示以下畫面。

更換語系

可以正常顯示語系值之後,接著來切換不同的語系,我們在 HomeController 裡面增加一個 ChangeLang() 的動作來執行切換語系,將語系名稱寫入 Cookie 就可以了。

編寫 View 語法

接著在前端新增呼叫切換語系的連結,在 \Views\Home\Index.cshtml 繼續加入以下語法。

完成後,再按 F5 測試一下專案,就會出現「中文」與「英文」的連結,點下去之後,上面的語系值就會跟著切換了。

更換資料庫欄位語系

我們已經設計了將語系資源檔顯示在畫面上了,但如果遇到從資料庫讀取的值要更換成不同語系該怎麼做呢?
我建議可以在資料庫內的欄位存放「語系 Key 值」,程式讀取 Key 值後,再依當時的語系名稱轉換。

我在 HomeController 的 Index() 裡面新增一段語法,取得資料庫欄位,然後將欄位的值轉換成語系值。

編寫 View 語法

接著在前端新增呼叫切換語系的連結,在 \Views\Home\Index.cshtml 繼續加入以下語法。

完成後,再按 F5 測試一下專案,在下方就會出現從資料庫欄位的值轉換語系,未來你就可以在資料表放「語系 Key 值」就行了,語系可以轉換成使用者語系。

JavaScript 顯示語系值

在 Razor 顯示語系的語法是 @Resources.Language.{語系Key值} 可是這樣的用法無法直接放在 *.js 的檔案裡面使用。
所以我使用了另一種方法,讓 *.js 檔案也可以呼叫。

OnActionExecuting() 事件裡面,將語系對照檔轉為 JavaScript 物件,然後放在 View 裡面,就可以呼叫物件的方法來取得語系值,
可在 OnActionExecuting() 事件加入以下語法。

新增 MyScript.js 檔案

我們在 Scripts 裡面增加一個 JavaScript 檔。

我們在 Scripts 裡面增加一個 JavaScript 檔

檔名就用 “MyScript” 示範。

然後在 “MyScript” 裡面放一個簡單的 alert 語法。

編寫 View 語法

接著在前端新增語法,顯示 JsLangObj 物件,引用 MyScript.js 檔案,並且寫一個測試按鈕來顯示語系值。
在 \Views\Home\Index.cshtml 繼續加入以下語法。

呼叫語系值的方法是 JsLangObj['{語系Key值}'],輸入 Key 就會顯示語系的內容。
呼叫的方法可以放在 *.js 檔案裡面也適用,只要注意順序就好,@(Html.Raw(ViewData["_JsLangObj"]));
要先執行才會產生可用的物件。

完成後,再按 F5 測試一下專案,按下「取得 JavaScript 語系值」,就可以在 JavaScript 顯示語系值了。

按下「取得 JavaScript 語系值」,就可以在 JavaScript 顯示語系值了

如果按 F12 檢視原始檔,可以發現其原理是產生 Key/Value 的物件而已,傳入 Key 可得到 Value。

產生 Key/Value 的物件而已

重點整理

  1. 資源檔加入各語系的檔案
  2. 資料表設計欄位管理語系值
  3. 提供方法將資料表寫入各語系資源檔
  4. 在 OnActionExecuting 顯示語系值
  5. 提供方法切換語系名稱寫入 Cookie
  6. 在 OnActionExecuting 將語系轉 js 物件
  7. 資料表欄位及 JavaScript 都可以轉換語系

範例下載

連結 GitHub 下載範例

相關學習文章

如果你在學習上有不懂的地方,需要諮詢服務,可以參考站長服務,我想辨法解決你的問題
如果文章內容有過時、不適用或錯誤的地方,幫我在下方留言通知我一下,謝謝

加入社團一起討論

關注我的 IG