ASP.NET2.0中的全球化與本地化之本地化
摘要:本文將通過一個實際案例來詳細剖析如何實現一個ASP.NET 2.0網站開發過程中的全球化與本地化問題。
一、簡介
全球化和本地化是每一位開發者在創建全球化產品或應用程序時必須清楚的兩個重要的慨念。盡管有許多文章對這個題目作過較好的解釋,但是我一直沒有看到一篇全面而綜合地討論關于全球化/本地化的所有重要概念的文章。本文旨在通過一個具體案例來詳細分析使用ASP.NET2.0開發一個web應用程序時所涉及到的全球化問題。
二、背景理論
全球化是應用程序開發中某一階段的任務,其目的是使程序能夠跨多個文化地區可用而不必顧及語言和地區性差別。例如,你在開發一個小型庫存管理程序,而你生活在例如英格蘭這樣一個以英語為主要語言的地區。現在,如果你想把你的程序賣到另一個不同國家,比方說是德國,那么你需要確保你的程序以德語顯示并實現輸入。
本地化是使用一種地區特定的文化和語言來創建內容、輸入和輸出數據的過程。文化將會影響日期顯示設置(如是mm/dd/yyyy還是dd/mm/yyyy),貨幣顯示格式等。現在,確保我們的程序能夠被本地化的過程稱為國際化或全球化。用更簡單的術語來說,全球化能夠被定義為一組活動,通過這一活動,可以確保我們的程序能夠運行在使用不同語言和文化的地區。
因此,全球化是與內在代碼的改變相關聯的以便支持這樣的改變,如使用資源文件等;而本地化是使用一種特定的文化和地區性信息的過程,以便該程序能夠使用本地的語言和文化。這意味著要把字符串翻譯成一個特定的本地的語言;為此,要把語言特定的字符串放到資源文件中。一般地,應該從主構建和代碼開發階段就開始考慮全球化問題,而本地化通常在以后才實現。
三、 實現ASP.NET 2.0網站的全球化
讓我們從一個簡單的示例開始。為了解釋本地化并使事情盡可能簡單,我使用ASP.NET和C#創建了一個稱為TestSite的新網站(詳見本文下載的源碼);我添加了一個MasterPage和一個缺省頁面。這個缺省頁面中含有一個TextBox和一個Calendar控件;該TextBox控件有一個描述貨幣的雙精度型實數。在本例中,我們會看到隨著用戶選擇不同的語言貨幣格式發生相應的變化。當我運行該應用程序時,此缺省頁面看起來如下所示:
我已經出版了這個測試web應用程序,你可以在下列URL處看到它的功能版本:http://63.134.215.124/testsite/default.aspx
四、 文化和本地化
首先,讓我先解釋一下文化和本地化。
一般地,語言也依賴于地理位置。例如,法語既是法國人的語言也是加拿大人的語言(除此之外,還有其它許多國家也說法語)。但是從語言角度來講,加拿大法語不同于法國法語。同樣,在美國英語和英國英語之間也存在一定的區別。因此,語言常常需要與說該語言的特定地區相聯系,并且這是通過使用本地化(語言+地理位置)實現的。
例如,fr是法語語言的代碼,而fr-FR意味著法國使用的法語。因此,fr僅指定了這種語言,而fr-FR才實現了本地化。同樣,fr-CA定義另一個代表加拿大法語和文化的本地化。如果我們僅僅使用fr,那么它僅代表是一種中立性質的文化(也即是,地區中立)。
那么,我們如何定義或改變當前文化呢?
在.NET FCL(框架類庫)的CultureInfo類中存在兩個屬性,我們可以通過重載該類的構造器來對它們進行設置,然后使用它來改變當前執行線程的文化:
1.UICulture:取得/設置當前執行線程的用戶接口。這個屬性幫助運行時刻從一個特定的資源文件(我們將在后面看到)中加載資源字符串。這個屬性能夠使用中立文化,也可以是本地化。例如:
或:
2.Culture:取得/設置地區特定的文化和貨幣、日期等的格式。這個屬性需要語言也需要位置(本地化)。
有時,我們需要一種不屬于任何語言或本地化的文化,對于任何地區/語言都不變。為此,我們可以使用CultureInfo.InvariantCulture屬性。這一屬性在內部系統處理期間使用;此時,要求是文化獨立的,或者存儲不需要被直接顯示給終端用戶的數據。
UICulture和Culture屬性都能夠在Web.Config文件的<GLOBALIZATION>屬性中進行定義。另外,它們還能夠在頁面級上被指定。但是,我們不想硬編碼這些值而是喜歡動態地設置它們。由上面可知,我們還能夠使用Thread.CurrentThread.CurrentCulture和Thread.CurrentThread.CurrentUICulture屬性以編碼方式得到/設置這些值。因此,我們將在本應用程序中使用這些屬性。
五、本地化切換
現在,回到我們的應用程序中來,我們需要一種方法實現本地化切換。為此,存在兩種方法:
1.使用瀏覽器設置:在IE中,用戶可以通過使用"Internet Options->General->Languages"來改變文化。為此,我們需要把Culture和UICulture都設置為auto并且把enableClientBasedCulture設置為true,如下所示:
< GLOBALIZATION culture="auto" uiculture="auto" enableClientBasedCulture=""true"" />
2.用戶指定的設置:我們能夠向用戶提供一個選項以便其在運行時刻指定和改變文化和語言。這是推薦的方法,因為有時瀏覽器本身可能沒有提供用戶特定的語言集(例如一個法語旅游者可能在印度上網)。而且,有時經由瀏覽器修改語言設置將會被阻斷。
現在,我們使用第二種推薦的方法,我在MasterPage上部(在一個面板控件內)創建了一個節;此處,我使用了一個具有這些語言選項的下拉列表框以便讓用戶選擇一種特定的本地化表達。
在本示例中,僅為了說明問題,我僅使用了四種語言選項:
Hindi,American English,British English和French。
為了實現我的應用程序的全球化,我的目標是:無論用戶何時選擇一種特定的本地化語言,下列都應該發生:
1.所有內容都應該是本地化的:這意味著,所有字符串和文本應該以選擇的語言和本地化顯示。
2.每個控件的標題(/內容)也應該以本地語言顯示文本。
3.日期和貨幣格式化應該根據選擇的本地化發生。
4.所有顯示給用戶的消息應該是使用本地的語言。
為了達到以上目的,你首先要確保從代碼中取出此內容并把它放在單獨的資源文件中,在.NET中這是一些具有.resx擴展名的簡單的XML文件。
由于這些內容將因語言不同而有所不同,所以,我們針對每一種文化(語言)各自建立了相應的資源文件。每一個這樣的文件中都提供了Name和Value兩個域。下面是在兩個資源文件中的示例入口;在此,假定我們必須輸入一個字符串"Welcome":
1.添加一個新的資源文件并命名它為TestSiteResource.resx,并且使用VS編輯器打開它。在Name域輸入"Banner",在Value域輸入"Test Website for Localization"。這個資源文件缺省使用的是美式英語。
2.添加另一個資源文件并命名它為"TestSiteResources.fr-FR.resx"。這個文件相應于法語字符串。在Name域中添加"Banner",在Value域中添加"Examinez le site Web pour le comportement de localisation"。
如果你想添加加拿大法語資源,那么,你需要創建另一個資源文件"TestSiteResources.fr-CA.resx"。這個名字的中間部分定義了本地化,并且它應該與通過UICulture屬性指定的相同。
3.這些文件將被保存在ASP.NET 2.0的App_GlobalResources文件夾下。
【提示】如果你僅想在某些頁面上顯示本地化字符串,那么,通過把資源文件放到App_LocalDirectory文件夾下,你可以在整個應用程序中限制本地化行為。這樣將使得本地化成為頁面特定的,而不是全應用程序范圍內的。這些命名應該如下所示(假定你僅想本地化一個名為MyPage.aspx的頁面):
MyPage.aspx.resx:這是MyPage.aspx的缺省的資源文件。
MyPage.aspx.fr-FR.resx:當文化改變為French時,將使用它,但是僅僅應用程序中的MyPage.aspx被本地化。
所有上面的.resx文件將被編譯到運行時刻程序集中。這些程序集被稱作"小程序集",并且為.resx文件提供了強類型包裝器。因此,我們不需要擔心在ASP.NET 2.0中由我們自己來創建資源程序集的問題。在你發行你的網站后,這些程序集被放在/bin文件夾下的單獨的文件夾中(名字為locale):
對于非ASP.NET應用程序,我們需要使用兩個工具:
1.資源文件生成器(resgen.exe);
2.程序集鏈接器(al.exe)。
在MSDN中存在大量有關如何使用這些工具的詳細信息。有興趣的讀者可以找來看看。
現在,既然我們已經針對不同文化和語言創建了資源文件,那么接下來,當用戶動態地改變文化時,我們需要一種方法來在運行時刻加載它們。幸好實現這一點在ASP.NET 2.0中相當容易。請見下面的代碼:
在這行代碼中,我們使用了Resources命名空間,它是由ASP.NET自動創建的,這時它把資源文件編譯成"小"程序集并且我們使用與我們創建的資源文件名相同的TestSiteResources類。然后,我們存取Welcome屬性,它將基于當前文化從資源文件中提供實際的文本。如果我們想得到標簽控件lblWelcome的文本,那么,我們可以使用ASP.NET 2.0中提供的兩個方法來進行相同的設置:
1.隱式本地化:在此,我們指定在控件定義中的新的元標簽并且讓ASP.NET基于resourcekey屬性從資源文件中取得該值:
為了使這能夠工作,我們需要把頁面特定的資源文件放到/App_LocalDirectory文件夾下。隱式本地化有助于縮小全局資源文件的大小并且有助于改進全局資源管理。當你有大部分頁面特定的內容時,你可以使用這種方法。
你不需要手工地做任何事情來設置這些隱式本地化屬性。只要在設計方式下打開你的web頁面,然后轉到"Tools->Generate Local Resources"。這將為你的頁面自動地創建一個資源文件。在Visual Studio 2005資源文件編輯器中,你僅需要針對每一個控件設置不同的域值(Control.Property)。
2.顯式本地化:當我們擁有全局資源文件時使用這一技術。在此,我們使用表達式來從資源文件中設置值,如下所示:
我們能夠使用VS IDE實現這種設置。選擇標簽控件,轉到其屬性窗口,選擇"Expressions->Text"。然后,從下拉框中選擇"Resources"并輸入類名(在這個示例中是,TestSiteResources)和Resource鍵(Banner)。這是本地化一個頁面中的UI控件的推薦方式。
3.以編程方式訪問強類型化資源類,如下所示:
這種方法可以工作,但是它需要針對頁面中的每一個控件進行編碼。因此,你可以對所有的控件使用第二種方法,而且使用這個方法來存取相應于其它內容的資源字符串(如果需要的話)。還應注意,象Calendar控件這樣的控件都實現了內置的本地化功能。一旦當前線程的UICulture和Culture發生改變,它就會自動地顯示本地化內容,這一切都歸功于ASP.NET!
一、簡介
全球化和本地化是每一位開發者在創建全球化產品或應用程序時必須清楚的兩個重要的慨念。盡管有許多文章對這個題目作過較好的解釋,但是我一直沒有看到一篇全面而綜合地討論關于全球化/本地化的所有重要概念的文章。本文旨在通過一個具體案例來詳細分析使用ASP.NET2.0開發一個web應用程序時所涉及到的全球化問題。
二、背景理論
全球化是應用程序開發中某一階段的任務,其目的是使程序能夠跨多個文化地區可用而不必顧及語言和地區性差別。例如,你在開發一個小型庫存管理程序,而你生活在例如英格蘭這樣一個以英語為主要語言的地區。現在,如果你想把你的程序賣到另一個不同國家,比方說是德國,那么你需要確保你的程序以德語顯示并實現輸入。
本地化是使用一種地區特定的文化和語言來創建內容、輸入和輸出數據的過程。文化將會影響日期顯示設置(如是mm/dd/yyyy還是dd/mm/yyyy),貨幣顯示格式等。現在,確保我們的程序能夠被本地化的過程稱為國際化或全球化。用更簡單的術語來說,全球化能夠被定義為一組活動,通過這一活動,可以確保我們的程序能夠運行在使用不同語言和文化的地區。
因此,全球化是與內在代碼的改變相關聯的以便支持這樣的改變,如使用資源文件等;而本地化是使用一種特定的文化和地區性信息的過程,以便該程序能夠使用本地的語言和文化。這意味著要把字符串翻譯成一個特定的本地的語言;為此,要把語言特定的字符串放到資源文件中。一般地,應該從主構建和代碼開發階段就開始考慮全球化問題,而本地化通常在以后才實現。
三、 實現ASP.NET 2.0網站的全球化
讓我們從一個簡單的示例開始。為了解釋本地化并使事情盡可能簡單,我使用ASP.NET和C#創建了一個稱為TestSite的新網站(詳見本文下載的源碼);我添加了一個MasterPage和一個缺省頁面。這個缺省頁面中含有一個TextBox和一個Calendar控件;該TextBox控件有一個描述貨幣的雙精度型實數。在本例中,我們會看到隨著用戶選擇不同的語言貨幣格式發生相應的變化。當我運行該應用程序時,此缺省頁面看起來如下所示:
![]() |
我已經出版了這個測試web應用程序,你可以在下列URL處看到它的功能版本:http://63.134.215.124/testsite/default.aspx
四、 文化和本地化
首先,讓我先解釋一下文化和本地化。
一般地,語言也依賴于地理位置。例如,法語既是法國人的語言也是加拿大人的語言(除此之外,還有其它許多國家也說法語)。但是從語言角度來講,加拿大法語不同于法國法語。同樣,在美國英語和英國英語之間也存在一定的區別。因此,語言常常需要與說該語言的特定地區相聯系,并且這是通過使用本地化(語言+地理位置)實現的。
例如,fr是法語語言的代碼,而fr-FR意味著法國使用的法語。因此,fr僅指定了這種語言,而fr-FR才實現了本地化。同樣,fr-CA定義另一個代表加拿大法語和文化的本地化。如果我們僅僅使用fr,那么它僅代表是一種中立性質的文化(也即是,地區中立)。
那么,我們如何定義或改變當前文化呢?
在.NET FCL(框架類庫)的CultureInfo類中存在兩個屬性,我們可以通過重載該類的構造器來對它們進行設置,然后使用它來改變當前執行線程的文化:
1.UICulture:取得/設置當前執行線程的用戶接口。這個屬性幫助運行時刻從一個特定的資源文件(我們將在后面看到)中加載資源字符串。這個屬性能夠使用中立文化,也可以是本地化。例如:
| Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr"); |
或:
| Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-CA"); |
2.Culture:取得/設置地區特定的文化和貨幣、日期等的格式。這個屬性需要語言也需要位置(本地化)。
| Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-A"); //正確,因為我們已經給出了本地化 Thread.CurrentThread.CurrentCulture = new CultureInfo("fr"); //錯誤,無法工作 |
有時,我們需要一種不屬于任何語言或本地化的文化,對于任何地區/語言都不變。為此,我們可以使用CultureInfo.InvariantCulture屬性。這一屬性在內部系統處理期間使用;此時,要求是文化獨立的,或者存儲不需要被直接顯示給終端用戶的數據。
UICulture和Culture屬性都能夠在Web.Config文件的<GLOBALIZATION>屬性中進行定義。另外,它們還能夠在頁面級上被指定。但是,我們不想硬編碼這些值而是喜歡動態地設置它們。由上面可知,我們還能夠使用Thread.CurrentThread.CurrentCulture和Thread.CurrentThread.CurrentUICulture屬性以編碼方式得到/設置這些值。因此,我們將在本應用程序中使用這些屬性。
五、本地化切換
現在,回到我們的應用程序中來,我們需要一種方法實現本地化切換。為此,存在兩種方法:
1.使用瀏覽器設置:在IE中,用戶可以通過使用"Internet Options->General->Languages"來改變文化。為此,我們需要把Culture和UICulture都設置為auto并且把enableClientBasedCulture設置為true,如下所示:
< GLOBALIZATION culture="auto" uiculture="auto" enableClientBasedCulture=""true"" />
2.用戶指定的設置:我們能夠向用戶提供一個選項以便其在運行時刻指定和改變文化和語言。這是推薦的方法,因為有時瀏覽器本身可能沒有提供用戶特定的語言集(例如一個法語旅游者可能在印度上網)。而且,有時經由瀏覽器修改語言設置將會被阻斷。
現在,我們使用第二種推薦的方法,我在MasterPage上部(在一個面板控件內)創建了一個節;此處,我使用了一個具有這些語言選項的下拉列表框以便讓用戶選擇一種特定的本地化表達。
在本示例中,僅為了說明問題,我僅使用了四種語言選項:
Hindi,American English,British English和French。
為了實現我的應用程序的全球化,我的目標是:無論用戶何時選擇一種特定的本地化語言,下列都應該發生:
1.所有內容都應該是本地化的:這意味著,所有字符串和文本應該以選擇的語言和本地化顯示。
2.每個控件的標題(/內容)也應該以本地語言顯示文本。
3.日期和貨幣格式化應該根據選擇的本地化發生。
4.所有顯示給用戶的消息應該是使用本地的語言。
為了達到以上目的,你首先要確保從代碼中取出此內容并把它放在單獨的資源文件中,在.NET中這是一些具有.resx擴展名的簡單的XML文件。
由于這些內容將因語言不同而有所不同,所以,我們針對每一種文化(語言)各自建立了相應的資源文件。每一個這樣的文件中都提供了Name和Value兩個域。下面是在兩個資源文件中的示例入口;在此,假定我們必須輸入一個字符串"Welcome":
1.添加一個新的資源文件并命名它為TestSiteResource.resx,并且使用VS編輯器打開它。在Name域輸入"Banner",在Value域輸入"Test Website for Localization"。這個資源文件缺省使用的是美式英語。
2.添加另一個資源文件并命名它為"TestSiteResources.fr-FR.resx"。這個文件相應于法語字符串。在Name域中添加"Banner",在Value域中添加"Examinez le site Web pour le comportement de localisation"。
如果你想添加加拿大法語資源,那么,你需要創建另一個資源文件"TestSiteResources.fr-CA.resx"。這個名字的中間部分定義了本地化,并且它應該與通過UICulture屬性指定的相同。
3.這些文件將被保存在ASP.NET 2.0的App_GlobalResources文件夾下。
【提示】如果你僅想在某些頁面上顯示本地化字符串,那么,通過把資源文件放到App_LocalDirectory文件夾下,你可以在整個應用程序中限制本地化行為。這樣將使得本地化成為頁面特定的,而不是全應用程序范圍內的。這些命名應該如下所示(假定你僅想本地化一個名為MyPage.aspx的頁面):
MyPage.aspx.resx:這是MyPage.aspx的缺省的資源文件。
MyPage.aspx.fr-FR.resx:當文化改變為French時,將使用它,但是僅僅應用程序中的MyPage.aspx被本地化。
所有上面的.resx文件將被編譯到運行時刻程序集中。這些程序集被稱作"小程序集",并且為.resx文件提供了強類型包裝器。因此,我們不需要擔心在ASP.NET 2.0中由我們自己來創建資源程序集的問題。在你發行你的網站后,這些程序集被放在/bin文件夾下的單獨的文件夾中(名字為locale):

對于非ASP.NET應用程序,我們需要使用兩個工具:
1.資源文件生成器(resgen.exe);
2.程序集鏈接器(al.exe)。
在MSDN中存在大量有關如何使用這些工具的詳細信息。有興趣的讀者可以找來看看。
現在,既然我們已經針對不同文化和語言創建了資源文件,那么接下來,當用戶動態地改變文化時,我們需要一種方法來在運行時刻加載它們。幸好實現這一點在ASP.NET 2.0中相當容易。請見下面的代碼:
| String welcome = Resources.TestSiteResources.Welcome; |
在這行代碼中,我們使用了Resources命名空間,它是由ASP.NET自動創建的,這時它把資源文件編譯成"小"程序集并且我們使用與我們創建的資源文件名相同的TestSiteResources類。然后,我們存取Welcome屬性,它將基于當前文化從資源文件中提供實際的文本。如果我們想得到標簽控件lblWelcome的文本,那么,我們可以使用ASP.NET 2.0中提供的兩個方法來進行相同的設置:
1.隱式本地化:在此,我們指定在控件定義中的新的元標簽并且讓ASP.NET基于resourcekey屬性從資源文件中取得該值:
| <asp:Label id=lblWelcome meta:resourcekey="lblWelcome" Text ="Welcome" runat=" server "></asp:Label> |
為了使這能夠工作,我們需要把頁面特定的資源文件放到/App_LocalDirectory文件夾下。隱式本地化有助于縮小全局資源文件的大小并且有助于改進全局資源管理。當你有大部分頁面特定的內容時,你可以使用這種方法。
你不需要手工地做任何事情來設置這些隱式本地化屬性。只要在設計方式下打開你的web頁面,然后轉到"Tools->Generate Local Resources"。這將為你的頁面自動地創建一個資源文件。在Visual Studio 2005資源文件編輯器中,你僅需要針對每一個控件設置不同的域值(Control.Property)。
2.顯式本地化:當我們擁有全局資源文件時使用這一技術。在此,我們使用表達式來從資源文件中設置值,如下所示:
| <asp:Label id=lblWelcome Text ="<%$ Resources:TestSiteResources, Welcome %>" runat=" server "> </asp:Label> |
我們能夠使用VS IDE實現這種設置。選擇標簽控件,轉到其屬性窗口,選擇"Expressions->Text"。然后,從下拉框中選擇"Resources"并輸入類名(在這個示例中是,TestSiteResources)和Resource鍵(Banner)。這是本地化一個頁面中的UI控件的推薦方式。

3.以編程方式訪問強類型化資源類,如下所示:
| lblWelcome.Text = Resources.TestSiteResources.Welcome; |
這種方法可以工作,但是它需要針對頁面中的每一個控件進行編碼。因此,你可以對所有的控件使用第二種方法,而且使用這個方法來存取相應于其它內容的資源字符串(如果需要的話)。還應注意,象Calendar控件這樣的控件都實現了內置的本地化功能。一旦當前線程的UICulture和Culture發生改變,它就會自動地顯示本地化內容,這一切都歸功于ASP.NET!
