多國語言使用Resource,並結合Database
承接上篇,如果User希望不要依據瀏覽器的語言設定,而是根據使用者個人選擇呢 !
這個時候我們因為是根據個人喜好,所以理所當然就會想到將設定檔記錄在Client Side,
而Client Side能想到的就是cookie
Server Side
Partial Class Resource
Inherits System.Web.UI.Page
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
Dim cLang As HttpCookie = HttpContext.Current.Request.Cookies("MyLanguage")
If cLang IsNot Nothing Then
System.Threading.Thread.CurrentThread.CurrentCulture = New System.Globalization.CultureInfo(cLang.Value)
System.Threading.Thread.CurrentThread.CurrentUICulture = New System.Globalization.CultureInfo(cLang.Value)
End If
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Response.Write("強型別:" + Resources.Resource.Love + "
")
End Sub
Protected Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
ChangeLanguage("en-US")
End Sub
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
ChangeLanguage("zh-TW")
End Sub
Sub ChangeLanguage(ByVal sLagn As String)
My.Response.Cookies.Add(New HttpCookie("MyLanguage", sLagn))
My.Response.Redirect(Request.Url.AbsoluteUri)
End Sub
End Class
Client Side
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="中文" />
<asp:Button ID="Button2" runat="server" Text="English" />
</div>
</form>
</body>
Display as below
如此便完成了語言切換的功能了。
========================================================
另外在寫這幾篇文章前就有個想法,如果我網頁一大堆中文,那我不是要在
resource內貼到昏倒嗎 ? 那把語言存進資料庫會不會比較好 ?
還是有人有更高明的方式去做多國語系呢 ?
如何將資料寫入資源檔 (自己回答自己問題) 2015/04/14
在這邊文章完成後一直有個疑問,如果我們的網站有一堆語系,那我不是要在不同的
Resource上貼到死,至於管理的問題也很麻煩,如果我的資源檔案上,有上萬筆資料
,我要改其中一筆,不就要進每個檔案找到頭昏眼花了嗎 ? 難不成每次有這樣的情況,就
必須把專案打開,進去資源檔案新增、修改、刪除 ? 而且上萬筆資料你能保證不重複建立
嗎 ? 我覺得這種事情應該有更好的解決方式,因此之前提到,我將語言存進資料庫,然後
載入各個不同語系的Resource檔,管理則交給DB (其實也可做個後台管理介面
,給企劃自行管理,這邊不討論),這樣感覺就好多了,這樣IT人員可以專心的處理程式上
的問題,而UI上的顯示就交給相關單位維護即可。
我的語系Table "LangList"長的如下
讀取多國語言From DataBase
Dim sSql As String = "select * from LangList where status=1"
Dim conn As New SqlConnection("連線字串")
Dim cmd As New SqlCommand(sSql, conn)
Dim rd As SqlDataReader
rd = cmd.ExecuteReader
'中文語系
Dim writer As New ResXResourceWriter(HttpContext.Current.Server.MapPath("~/App_GlobalResources/Resource.resx"))
While rd.Read
writer.AddResource(rd("英文"), rd("中文"))
End While
writer.Close()
我這邊以單一語系做個範例而已,當然在讀取、寫入哪個資源檔的程式碼,
,其實可以寫成陣列去跑迴圈,程式碼就不詳述。
我想大家應該都會想到,每次去連DB重Load資源檔,那不是挺耗效能的,
所以我的DB會設計個欄位"Status",Status=1時,代表新增,這樣就不用讀取
一堆資料囉 ! 這些後續的變化就交給要使用的人自行規畫囉 !
或許有人在測試這段程式碼的時候發現,當我將DB內的資料寫入時,原本資源檔
內的資料反而清空了,只留下新增的資料,資料並不會疊加上去,我是先把資源檔
的內容讀出,然後在寫入,如下
Dim writer As New ResXResourceWriter(HttpContext.Current.Server.MapPath("~/App_GlobalResources/Resource.resx"))
'讀取原Resource的內容
Dim reader As New ResXResourceReader(HttpContext.Current.Server.MapPath("~/App_GlobalResources/Resource.resx"))
For Each dataAs DictionaryEntry In reader
writer.AddResource(data.Key.ToString(), data.Value.ToString())
Next
'這裡新增要從DB讀取的資料,並寫入至Resurce(請加入讀取多國語言From Databases那段)
writer.Close()
reader.Close()
PS. 記得 Imports System.Resources,才能使用ResXresourceWriter哦 !
補充:(解答在此篇)
另外我有試過把Page_init內的程式碼搬移到Gloabal內的Application_Start,
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
' 應用程式啟動時執行的程式碼
'將切換語系的功能搬移到Global內確無法變換,真是耐人尋味
Dim cLang As HttpCookie = HttpContext.Current.Request.Cookies("MyLanguage")
If cLang IsNot Nothing Then
System.Threading.Thread.CurrentThread.CurrentCulture = New System.Globalization.CultureInfo(cLang.Value)
System.Threading.Thread.CurrentThread.CurrentUICulture = New System.Globalization.CultureInfo(cLang.Value)
End If
End Sub
奇怪的是,查看cookies的value是en-US
查看瀏覽器預設語言
實際執行的時候還是顯示中文,這點倒是令我疑惑了很久,照理來說執行順序應該是
Application_Start --> Page_init --> Page_load
以這樣的順序應該也會套用到才是,如果有看官知道原因,希望能不吝指點。