Asp.net - 多國語系-使用Resource (二)

  • 3746
  • 0
  • 2015-04-22

多國語言使用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

以這樣的順序應該也會套用到才是,如果有看官知道原因,希望能不吝指點。