1. 程式人生 > >ASP.NET 2.0 本地化技術之研究

ASP.NET 2.0 本地化技術之研究

眾所周知ASP.NET 2.0裡對本地化(Localization)做了很多工作,大大簡化了開發過程。今天終於能抽出時間研究一下這個技術了,資料很多,但大多帶著一股咬文嚼字的翻譯味道,So......自己寫一篇。

1.使用工具自動生成本地化資源(LocalResources)
2.原來Localizable AttributeProperty是這麼回事呀
3.手工新增本地化資源
4.顯示使用本地化資源
5.全域性資源的使用(GlobalResources)
6.如何在後臺程式設計時使用這兩種資源
7.程式設計切換語言設定
8.使用圖片資源
9.程式碼下載


1.使用工具自動生成本地化資源(LocalResources)

首先當然是建立一個WEB工程啦,如圖所示:


雙擊Default.aspx,切換到[設計]檢視,從工具箱裡拖一個Button進來。點選選單中的[工具]->[生成本地資源],如圖所示:


這時發現在解決方案方案視圖裡自動增加了一份本地資源,如下圖所示:


切換到屬性檢視,可以看到Text和ToolTip都被加上了一個紅色符號,提示“屬性是用表達形式隱式繫結的”,如下圖所示:(注意:只有在檢視狀態下選中控制元件才能看到這兩個屬性喲


為了增加對多語言的支援,我們現在右鍵Default.aspx.resx,點選複製,再選中App_LocalResources目錄,點選貼上,將“副本 Default.aspx.resx”重新命名為Default.aspx.en-us.resx,如圖所示:


分別編輯Default.aspx.resx和Default.aspx.en-s.resx 的內容,如下圖示:
Default.aspx.resx


Default.aspx.en-s.resx


執行網站,效果如下圖所示:


點選IE選單的[工具]->[Internet 選項],在彈出的對話方塊中點[常規]選項卡的[語言]按鈕,彈出[語言首選項]對話方塊,如下圖所示:


點選[新增]按鈕,選擇英語(美國),並上移到第一位,如下圖所示:


一路[確定]點下來,重新整理頁面,可以看到Button的標題變成“Hello World”啦,如下圖所示:


綜上所述,使用工具自動生成本地化資源,並隱式的繫結到控制元件上,來實現頁面的本地化是非常簡單的,但存在以下幾項問題:

    1)必須為每個頁生成多份資原始檔;
    2)只有控制元件屬性中被標識為Localizable(true)才可能被工具掃描到;
    3)由於是對頁面包含的控制元件進行掃描,所以最好是在頁面佈局基本確定後再使用該工具,並且在編輯完    資原始檔後不要再使用該工具,如果不幸你這樣做了。。。會發現預設的資原始檔被清空了

2.原來Localizable AttributeProperty是這麼回事呀

在我前天寫的隨筆開發和使用自定義伺服器控制元件中,一直對屬性為什麼要使用Localizable(true)不清楚。
        [
        Bindable(
true),
        Category(
"Appearance"),
        DefaultValue(
"Hello"),
        Description(
"The welcome message text."),
        Localizable(
true)
        ]
        
publicvirtualstring Text
        {
            
get
            {
                
string s = (string)ViewState["Text"];
                
return (s ==null?"Hello" : s;
            }
            
set
            {
                ViewState[
"Text"= value;
            }
        }

查了許多關於WEB控制元件開發的資料,其中都對這個AttributeProperty做了忽略,原來只有當控制元件的屬性宣告為Localizable(true)時,VS的生成本地資源工具才會掃描到。
3.手工新增本地化資源

第一點中提到過生成本地資源工具只能掃描到頁面已經包含的控制元件,那麼如果後面由於開發需要又增加了一個新的控制元件要怎麼辦呢?雖然大部人都能自己想到,但還是寫一下吧。

從工具箱再拖一個Label控制元件到頁面上,切換到源檢視,修改程式碼如下:
<asp:Label ID="Label1" runat="server" meta:resourcekey="Label1Resource1" Text="Label"></asp:Label>
再修改兩份本地資原始檔,為Label1新增Label1Resource1鍵值的相關資源,如下圖所示:
Default.aspx.resx


Default.aspx.en-s.resx


再執行程式,切換語言設定,可以看到Label1的效果和Button1是一樣的,如圖所示:
中文(中國)


英語(美國)


4.顯示使用本地化資源

OK,前面提到的都是隱式使用本地化資源,那麼如何顯示的使用本地化資源呢?相對於隱式來講,顯示更加靈活,功能也更強大。

只需要將剛才的Label1的程式碼,
<asp:Label ID="Label1" runat="server" meta:resourcekey="Label1Resource1" Text="Label"></asp:Label>
修改為,即可。
<asp:Label ID="Label1" runat="server" 
    Text
="<%$ Resources:Label1Resource1.Text %>" 
    ToolTip
="<%$ Resources:Label1Resource1.ToolTip %>"></asp:Label>
這時切換到[設計]檢視,選中Label1控制元件,檢視屬性檢視,會發現Text和ToolTip被加上的是藍色的符號,提示“屬性綁定了表示式”。跟上面提到的紅色符號比較,少了“隱式”二字,這也就是所謂的顯式和隱定的來源吧,如下圖所示:


5.全域性資源的使用(GlobalResources)

前面提到過,本地資源需要為每個頁面分別生成多個資原始檔,雖然這樣看起來分門別類的挺清楚,但在實際應用過程中,我們有許多資源是可以共享的,總不能不停的重複寫來寫去吧。其實這種情況我們可以用全域性資源(GlobalResources)來解決。

在資源方案檢視中選中網站,右鍵,點選[新增ASP.NET 資料夾]->[App_GlobalResources],如圖所示:


再選中App_GlobalResources資料夾,右鍵,點選[新增新項],在彈出的對話方塊中選中“資原始檔”,命名為“LocalizedText.resx”,點選[新增],如圖所示:


雙擊LocalizedText.resx進行編輯,新增一條新的字串資源,如圖所示:


複製LocalizedText.resx,貼上到App_GlobalResources目錄,重新命名為LocalizedText.en-us.resx,雙擊進行編輯,新增一條新的字串資源,如圖所示:


開啟Default.aspx,切換到[設計]檢視,從工具箱拖一個TextBox控制元件到頁面上。切換到[源]檢視,修改程式碼:
<asp:TextBox ID="TextBox1" runat="server" Text="<%$ Resources:LocalizedText, Msg1 %>"></asp:TextBox>
執行程式,切換語言設定,可以看到全域性資源的使用效果了,如圖所示:
中文(中國)


英語(美國)


注意:全域性資源不能使用隱式宣告。

6.如何在後臺程式設計時使用這兩種資源

前面提到的都是在網頁中使用這兩種資源,那麼如何在後臺使用這兩種資源呢?

開啟Default.aspx,切換到[設計]檢視,從工具箱拖一個Localize控制元件(Literal 控制元件與 Label 控制元件類似,但 Literal 控制元件不允許對所顯示的文字應用樣式。可以通過設定 Text 屬性,以程式設計方式控制在控制元件中顯示的文字。)到頁面上。雙擊Button1,新增以下實現
protectedvoid Button1_Click(object sender, EventArgs e)
    {
        Localize1.Text 
= (String)GetLocalResourceObject("Label1Resource1.Text"+""+
            (String)GetGlobalResourceObject(
"LocalizedText""Msg1");
    }

記得添上這個引用
using System.Globalization;
執行程式,切換語言設定,可以看到和前面使用表示式呼叫資源的效果是一樣的,如圖所示:
中文(中國)


英語(美國)


7.動態切換語言設定

以上的介紹都是通過IE瀏覽器獲取語言設定,其實我們可以自己設定使用哪種語言。

1)通過在每個頁面裡的Page節指定
<%@ Page Culture="en-us" UICulture="en-us"%>
如上所設,該頁將使用en-us的語言設定。

注意:這只是個概要式寫法,實際的頁面中的Page一般都包含更多的屬性。

2)通過在Web.Config裡的globalization節指定
<system.web><globalization Culture="en-us" UICulture="en-us"/></system.web>
3)當然還有一種就是通過程式設計動態切換語言設定啦,這也是實際專案中經常用到的方式

開啟Default.aspx,切換到[源]檢視,新增如下程式碼
<href="?currentculture=zh-cn">中文(中國)</a>&nbsp;<href="?currentculture=en-us">English(USA)</a>
開啟Default.aspx.cs,新增如下程式碼
    String s;

    
protectedoverridevoid InitializeCulture()
    {
        s 
= Request.QueryString["currentculture"];
        
if (!String.IsNullOrEmpty(s))
        {
            
//UICulture - 決定了採用哪一種本地化資源,也就是使用哪種語言
            
//Culture - 決定各種資料型別是如何組織,如數字與日期            Thread.CurrentThread.CurrentUICulture =new CultureInfo(s);
            Thread.CurrentThread.CurrentCulture 
= CultureInfo.CreateSpecificCulture(s);
        }
    }

記得添上這個引用
using System.Threading;
執行程式,分別點選新增加的兩個連結,效果如圖所示:
中文(中國)


Enlish(USA)



8.使用圖片資源

分別編輯LocalizedText.resx和LocalizedText.en-su.resx,新增圖片資源,如圖所示:
LocalizedText.resx


LocalizedText.en-su.resx


注意:當圖形檔案新增到圖形資源裡時,系統會自動去除副檔名並把“-”替換成“_”,如上圖,我的檔名為“en-us-flag.png”新增到資源裡變成了“en_us_flag”。

開啟Default.aspx,切換到[設計]檢視,從工具箱拖一個Image控制元件到頁面上。開啟Default.aspx.cs,新增如下程式碼
protectedvoid Page_Load(object sender, EventArgs e)
    {
        Image1.ImageUrl 
="~/Image.aspx?currentculture="+ s;
    }

選中網站右鍵,建立一個新的WEB窗體,命名為Image.aspx,編輯該頁面,在Page節增加如下程式碼
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Image.aspx.cs" Inherits="Image" Culture="auto" UICulture="auto"%>
注意:預設建立的WEB窗體的Page節,不包括Culture和UICulture這兩個屬性,一定要手工添上,切記!

開啟Image.aspx.cs,新增如下程式碼
protectedoverridevoid InitializeCulture()
    {
        String s 
= Request.QueryString["currentculture"];
        
if (!String.IsNullOrEmpty(s))
        {
            
//UICulture - 決定了採用哪一種本地化資源,也就是使用哪種語言
            
//Culture - 決定各種資料型別是如何組織,如數字與日期            Thread.CurrentThread.CurrentUICulture =new CultureInfo(s);
            Thread.CurrentThread.CurrentCulture 
= CultureInfo.CreateSpecificCulture(s);
        }
    }

    
protectedvoid Page_Load(object sender, EventArgs e)
    {
        System.Drawing.Bitmap img 
= (System.Drawing.Bitmap)GetGlobalResourceObject(
            
"LocalizedText",
            CultureInfo.CurrentCulture.Name.ToLower().Replace(
"-""_"+"_flag");

        System.IO.MemoryStream ms 
=new System.IO.MemoryStream();
        img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);

        Response.ClearContent();
        Response.ContentType 
="image/jpeg";
        Response.BinaryWrite(ms.ToArray());

        img.Dispose();
        ms.Dispose();
        ms.Flush();
    }

當然,別忘了添上這兩個引用 using System.Threading;
using System.Globalization;
執行程式,分別點選兩個連結,效果如圖所示:
中文(中國)


English(USA)