摘要:隨著計(jì)算機(jī)網(wǎng)絡(luò)的發(fā)展,一些商業(yè)機(jī)構(gòu)也開(kāi)始向國(guó)際市場(chǎng)邁進(jìn)。因此這些商業(yè)的機(jī)構(gòu)的網(wǎng)站也開(kāi)始面向全世界的用戶,要求網(wǎng)站具有多語(yǔ)言的選擇,實(shí)現(xiàn)本地化。在.NET1.1框架下面,如果你要實(shí)現(xiàn)本地化,你可能要借助某些插件,甚至要編寫(xiě)一連串的代碼;但是在.NET2.0框架底下,你會(huì)發(fā)現(xiàn)一切原來(lái)是那么的簡(jiǎn)單~~!
主要內(nèi)容:
1. 簡(jiǎn)單例子
2. 進(jìn)一步認(rèn)識(shí)Localization
3. 語(yǔ)言轉(zhuǎn)換
4. 解決方案
一. 簡(jiǎn)單例子
下面通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)說(shuō)明利用Localization來(lái)實(shí)現(xiàn)本地化是那么的簡(jiǎn)單,首先我們打開(kāi)Visual Studio 2005,新建一個(gè)名叫Localization的工程(名字就無(wú)關(guān)緊要了,隨你喜歡~~),如下所示:
然后我們?cè)贒efault.aspx這張頁(yè)面上放一些控件,例如我們?cè)陧?yè)面上放一個(gè)按鈕,一個(gè)標(biāo)簽一個(gè)文本框,添加完之后的頁(yè)面就好像下面的一樣:
接下來(lái)的一步主要是負(fù)責(zé)生成本地資源,我們點(diǎn)擊“工具->生成本地資源(R)”,
于是我們的項(xiàng)目中多了一個(gè)文件夾App_LocalResources,里面包含一個(gè)文件Default.aspx.resx,而這個(gè)文件就是用來(lái)編輯保存我們想要顯示的一些文字資源,
例如我們?yōu)槲覀兲砑拥目丶斎胍韵滦畔ⅲ?BR>
在完成以上步驟之后,我們就可以看到效果了。
在以上的步驟中,我們沒(méi)有手工編寫(xiě)任何代碼,而由.NET2.0自動(dòng)實(shí)現(xiàn)綁定過(guò)程。而頁(yè)面跟以往的不同就是HTML代碼發(fā)生了變化:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>無(wú)標(biāo)題頁(yè)</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" meta:resourcekey="Button1Resource1" Text="Button" />
<asp:TextBox ID="TextBox1" runat="server" meta:resourcekey="TextBox1Resource1"></asp:TextBox>
<asp:Label ID="Label1" runat="server" meta:resourcekey="Label1Resource1" Text="Label"></asp:Label></div>
</form>
</body>
</html>

除了Page里面增加了Culture="auto" meta:resourcekey="PageResource1" UICulture="auto"等屬性設(shè)置外,我們添加的控件也相應(yīng)的多了meta:resourcekey這個(gè)屬性,而.NET2.0就是根據(jù)這些屬性來(lái)進(jìn)行語(yǔ)言綁定。
在上述的簡(jiǎn)單項(xiàng)目中,我們只提供了一種語(yǔ)言,還沒(méi)達(dá)到本地化的要求,于是我們向App_localresources這個(gè)目錄手工增加一個(gè)資源文件Default.aspx.en-us.resx文件(其中英文[美國(guó)]的語(yǔ)言代碼是"en-us"),我們向里面添加一些key/value對(duì),如下所示:
然后我們?nèi)バ薷腎E的Internet選項(xiàng)的語(yǔ)言,添加“英文(美國(guó))[en-us]”,并且把它移動(dòng)到最上面:
再運(yùn)行一次我們的項(xiàng)目,你會(huì)發(fā)現(xiàn)簡(jiǎn)單的本地化已經(jīng)實(shí)現(xiàn),
至此,通過(guò)一個(gè)簡(jiǎn)單的例子,我們已經(jīng)初步認(rèn)識(shí)了.NET2.0是如何實(shí)現(xiàn)利用Localization來(lái)實(shí)現(xiàn)本地化的。但是如果我們要構(gòu)建一個(gè)優(yōu)秀的國(guó)際化網(wǎng)站或軟件,我們需要對(duì)Localization做進(jìn)一步的認(rèn)識(shí)。
二. 進(jìn)一步認(rèn)識(shí)Localization
到了這里,你會(huì)發(fā)現(xiàn)上述的頁(yè)面中是每一個(gè)頁(yè)面對(duì)應(yīng)一些屬于自己的資源文件,如果我們要求多張頁(yè)面或者全部頁(yè)面都要用同一個(gè)資源文件的時(shí)候,該怎么做呢?很簡(jiǎn)單,我們可以在項(xiàng)目中添加一個(gè)文件夾,名叫App_GlobalResources,這是系統(tǒng)默認(rèn)的存放全局資源的目錄。例如我們?cè)谌帜夸浿刑砑觾蓚(gè)文件,分別是global.resx和global.en-us.resx,
然后我們分別在里面輸入一些對(duì)應(yīng)的key/value值,至于怎么應(yīng)用我們的全局資源綁定到頁(yè)面中,我們有兩種方法:
一種是在HTML代碼里面進(jìn)行綁定,表達(dá)式是 <%$ resources: [applicationkey], resourcekey, [default] %>,例如我們?cè)贒efault.aspx多放一個(gè)按鈕,其HTML代碼為:
<asp:Button ID="Button2" runat="server" Text="<%$ resources: global, String1 %>于是我們會(huì)得到以下的效果,可以看出資源已綁定到控件上。
另一種方式則是在程序代碼進(jìn)行綁定,由于.NET2.0框架會(huì)將全局資源文件編譯成一個(gè)類,也就是說(shuō)我們剛才創(chuàng)建的global.resx文件將被編譯成一個(gè)類global,而資源文件里面的所有key將成為類的屬性,以供在程序里進(jìn)行訪問(wèn)。例如我們可以在程序里這樣寫(xiě):
this.Button2.Text = Resources.global.String1;大家等會(huì)可以下載附件嘗試一下,看看效果是否一樣~~~~
另外,資源文件除了可以存放一些字符串之外,還可以存放圖片,聲頻,文件等等,
例如我們?cè)谫Y源文件中添加一些圖片資源,你可以將圖片設(shè)置為在編譯時(shí)鏈接或者嵌入到資源文件,
而在程序代碼里面,我們得到的將是System.Drawing.Bitmap類型的變量,至于添加其他類型的文件,得到的是什么,這里不多說(shuō)了,大家自己探討一下吧。
三. 語(yǔ)言設(shè)置
大家是否覺(jué)得如果每次都要去Internet選項(xiàng)來(lái)進(jìn)行語(yǔ)言的選擇會(huì)很麻煩,那么如何在自己的項(xiàng)目中設(shè)置要顯示某一種語(yǔ)言呢?很簡(jiǎn)單,通常我們有三種途徑。首先需要講兩個(gè)屬性,一個(gè)是Culture,這個(gè)決定各種數(shù)據(jù)類型是如何組織,如數(shù)字與日期;另一個(gè)是UICulture,這個(gè)就決定了采用哪一種本地化資源,也就是使用哪種語(yǔ)言。詳細(xì)請(qǐng)看MSDN~~~
1. 在具體頁(yè)面進(jìn)行設(shè)置
如上,由于將UICulture和Culture屬性都設(shè)置成auto,.NET2.0會(huì)根據(jù)你的Internet語(yǔ)言選項(xiàng)來(lái)確定加載哪些資源文件,當(dāng)然你也可以將UICulture和Culture都設(shè)置成"en-us",那么這張頁(yè)面所加載的就是英文的資源文件了。不過(guò)這樣寫(xiě)很麻煩,每一張頁(yè)面都要寫(xiě),太繁瑣了,于是我們可以在web.config里面設(shè)置我們所要的語(yǔ)言。
2. 在web.config里面進(jìn)行設(shè)置
<system.web>
<globalization culture="en-us" uiCulture="en-us"/>
</system.web>
</configuration>
通過(guò)這樣設(shè)置,項(xiàng)目中的全部頁(yè)面就會(huì)自動(dòng)加載英文資源文件了,但要注意的一點(diǎn)是,如果在頁(yè)面中也設(shè)置了UICulture和Culture屬性,那么它將覆蓋web.config里面的設(shè)置。例如某張頁(yè)面的這兩個(gè)屬性設(shè)為"zh-cn",那么這張頁(yè)面將顯示中文而不是英文。但還是覺(jué)得不好,因?yàn)轫?yè)面要加載的語(yǔ)言文件都寫(xiě)死了,不靈活。
3. 在代碼里面進(jìn)行設(shè)置
using System.Threading;
// Set the culture to the browser's accept language
Thread.CurrentThread.CurrentCulture =
CultureInfo.CreateSpecificCulture(Request.UserLanguages[0]);
// Set the user interface culture to the browser's accept language
Thread.CurrentThread.CurrentUICulture =
new CultureInfo(Request.UserLanguages[0]);
在程序代碼里面進(jìn)行設(shè)置,重載頁(yè)面的InitializeCulture事件,注意在代碼里的語(yǔ)言設(shè)置,會(huì)覆蓋頁(yè)面的HTML屬性或者web.config的設(shè)置。上述的Request.UserLanguages[0]是獲取Internet語(yǔ)言選項(xiàng)的第一種語(yǔ)言代碼。
四. 解決方案
經(jīng)過(guò)上述的初步和進(jìn)一步的認(rèn)識(shí),相信大家已經(jīng)理解了Localization的原理以及實(shí)現(xiàn)方法,但真要在我們的系統(tǒng)中實(shí)現(xiàn)多語(yǔ)言,實(shí)現(xiàn)本地化,我們應(yīng)該怎樣來(lái)架構(gòu)呢?
通常我們?yōu)榱藴p少重復(fù)代碼,我們一般是建立一個(gè)基頁(yè)面PageBase類,讓所有的頁(yè)面都繼承基頁(yè)面,在基頁(yè)面重寫(xiě)InitializeCulture事件,而用戶所選擇的語(yǔ)言我們可以儲(chǔ)存在Session,Cookie,QueryString或者.NET2.0提供的profile里面。 下面我們以存儲(chǔ)在Session為例,構(gòu)建我們的基頁(yè)面,為簡(jiǎn)單起見(jiàn),我只是通過(guò)一個(gè)按鈕來(lái)選擇語(yǔ)言,真正實(shí)現(xiàn)的時(shí)候可能會(huì)用一個(gè)下拉框:
主頁(yè)面:
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Localization;

/// <summary>
/// 本地化
/// kenneth
/// 2006.07.16
/// </summary>
public partial class _Default : MyPageBase{
protected void Page_Load(object sender, EventArgs e)
{
this.Button2.Text = Resources.global.String1;
}
protected void Button2_Click(object sender, EventArgs e)
{
if (Session["PreferredCulture"].ToString().ToUpper() == "EN-US")
Session["PreferredCulture"]= "zh-cn";
else if (Session["PreferredCulture"].ToString().ToUpper() == "ZH-CN")
Session["PreferredCulture"] = "en-us";
//重定向頁(yè)面
Response.Redirect(Request.Url.PathAndQuery);
}
}
基頁(yè)面MyPageBase:
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Threading;
using System.Globalization;
namespace Localization
{
/// <summary>
/// MyPageBase 基類實(shí)現(xiàn)本地化
/// kenneth
/// 2006.07.16
/// </summary>
public class MyPageBase : System.Web.UI.Page
{
protected override void InitializeCulture()
{
// 用Session來(lái)存儲(chǔ)語(yǔ)言信息
if(Session["PreferredCulture"] == null)
Session["PreferredCulture"] = Request.UserLanguages[0];
string UserCulture = Session["PreferredCulture"].ToString();
if (UserCulture != "")
{
//根據(jù)Session的值重新綁定語(yǔ)言代碼
Thread.CurrentThread.CurrentUICulture = new CultureInfo(UserCulture);
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(UserCulture);
}
}
}
}
好了,終于寫(xiě)完了,希望大家頂一下。這幾天攻了一下MSDN,寫(xiě)出自己的心得,如有雷同,純屬巧合,謝謝支持!最后,給出自己的模板,供大家參考一下~~~

