ASP.NET 2.0 中的資源與本地化

來源:互聯網
上載者:User
發布日期: 2006-08-22 | 更新日期: 2006-08-22

Ted Pattison

下載本文的代碼:BasicInstincts2006_08.exe (878KB)

討論 ASP.NET 2.0 中網站的本地化。

我假設您熟悉地區性 UI 和地區性設定、CultureInfo 對象、資源檔、ResourceManager 類和自動產生的強型別化資源類。並且,我還假設您基本瞭解 Microsoft .NET Framework 是從預設程式集、還是從本地化衛星程式集載入資源的確定機制。如果您需要更多有關這些主題的背景知識,可先讀一下我在 2006 年 5 月發表的 Basic Instincts(英文)專欄文章,然後再繼續閱讀本文。

控制頁面層級的地區性設定

利用 ASP.NET 2.0 可輕鬆地逐頁更改地區性設定。您只需將 UICulture 和 Culture(地區性)屬性添加到 .aspx 等類似頁面內的 Page 指令即可。

<%@ Page UICulture="fr" Culture="fr-BE" %>

在頁面生命週期的早期,一個以這些屬性設定啟動並執行 .aspx 頁,將使用合適的 CultureInfo 對象初始化當前線程的 CurrentUICulture 屬性和 CurrentCulture 屬性。在測試期間,如果將以上所示屬性添加到一個 .aspx 檔案,然後再添加一個內建的 ASP.NET Web 控制項(如 Calendar(日曆)控制項),您會立即看到一切運轉正常, 1 所示。左側的 Calendar(日曆)控制項已呈現在地區性設定為 en-US 的頁面上,而右側的 Calendar(日曆)控制項則呈現在地區性設定為 fr-BE 的頁面上。

圖 1 本地化的日曆控制項

然而,在大多數生產網站中,像這樣將特定地區性設定寫入程式碼到頁面中是行不通的。而使用不同語言的使用者將看到同一頁面的不同的本地化內容。如果您向 UICulture 和 Culture(地區性)屬性都分配一個“auto”值,則 ASP.NET 將基於每個請求自動為您初始化地區性設定。

<%@ Page UICulture="auto" Culture="auto" %>

ASP.NET 通過檢查瀏覽器發送的 HTTP 標題來初始化這些設定。通過更改 Internet Options(Internet 選項)對話方塊中的語言喜好設定設定,您可以在 Internet Explorer 中測試頁面的不同語言版本。

通常,您會想要網站中的所有頁面都符合相同的地區性設定。您可以為 UICulture 和 Culture(地區性)屬性分配一個網站範圍的“auto”值,這樣就不必分別為每個頁面進行分配了。只需將以下元素添加到位於網站的根處的 web.config 檔案中即可:

<globalization uiCulture="auto" culture="auto" />

除了自動化佈建以外,您還可以為 ASP.NET 指定一個預設區域性(如果它無法找到 HTTP 標題來確定使用者的首選地區性):

<globalization uiCulture="auto:en" culture="auto:en-US" />

使用設定檔跟蹤語言喜好設定

雖然自動化佈建的確會使事情變輕鬆,但它對於使用者來說並不總是那麼方便。例如,假設某位使用者更願意閱讀英語版的技術類網站和法語版的商業類網站。當他在兩個網站之間來迴轉換時,需要不斷地更改瀏覽器設定,他會感到非常煩惱。該使用者將非常喜歡能夠讓其選擇語言喜好設定的網站。

要瞭解如何產生能夠使使用者更輕鬆地在不同語言間來回切換的 UI 和支援性實現,可以下載本月的程式碼範例 - 一個名為 LitwareWebApp 的 ASP.NET 2.0 網站。它的 UI 2 所示。

圖 2a 英語版本

圖 2b 語言版本

LitwareWebApp 網站使用 ASP.NET 2.0 中引入的新的設定檔功能,來跟蹤使用者的語言喜好設定。您可以添加一個名為 LanguagePreference 的基於字串的設定檔屬性,通過將以下元素添加到網站的 web.config 檔案,來支援匿名識別:

<configuration>
<system.web>
<anonymousIdentification enabled="true"/>
<profile>
<properties>
<add name="LanguagePreference" type="string"
defaultValue="Auto" allowAnonymous="true" />
</properties>
</profile>
</system.web>
</configuration>

LitwareWebApp 網站被設計為具有“主版頁面”內的標準布局,該“主版頁面”包含一個名為 lstLanguage 的 RadioButtonList 控制項。請注意,該控制項不僅顯示友好的語言名稱(如美國英語和比利時法語),而且還會使用 SelectedValue 屬性跟蹤真正的地區性名稱(如 en-US 和 fr-BE)。當使用者更改語言喜好設定時,lstLanguage 控制項的 SelectedIndexChanged 事件會引發並執行以下代碼來更新 LanguagePreference 設定檔屬性:

Profile.LanguagePreference = lstLanguage.SelectedValue
Response.Redirect(Me.Request.Url.AbsolutePath)

如果調用 Response.Redirect,則會強制發生一次從瀏覽器到 Web 服務器的新往返程,從而在使用所需的語言喜好設定設定了設定檔屬性後,重新啟動頁面的生命週期。

之後要處理的事情是以編程方式,於合適的時間在頁面生命週期內調整地區性設定。在 ASP.NET 2.0 中執行此操作的正確方法是替換名為 InitializeCulture 的 Page 類。頁面生命週期已被設計為,在頁面本身或其任何子控制項使用本地化資源進行任何工作前,始終調用 InitializeCulture。

樣本網站的設計要求您向網站內的各頁面添加一個替換的 InitializeCulture 實現。不幸的是,您無法在“主版頁面”層級上替換 InitializeCulture 方法,因為 MasterPage 類不會從 Page 類繼承。另外,為網站內的各頁面分別替換 InitializeCulture 方法非常冗長乏味。會導致許多重複實現,從而引發嚴重的維護問題。

一個用於初始化地區性設定的網站範圍的更有效方法是,建立一個公用的 Page 派生基類,然後讓所有 .aspx 頁檔案從該類繼承,我在 LitwareWebApp 樣本網站中就是這麼做的。我的名為 LitwarePage(請參閱圖 3)的 Page 派生基類是在名為 LitwarePage 的源檔案中定義的,並且已被添加到 App_Code 目錄,這樣一來它就可以由 ASP.NET 自動編譯並可用於當前網站中的其他代碼。

建立了 Page 派生基類後,即可將 .aspx 頁定義更新為從該類而不是從標準 Page 類派生。例如,您可以在 default.aspx.vb 內對局部類進行此類修改。

Partial Class _Default : Inherits LitwarePage
'*** 頁面類定義位於此處
End Class

此時,我擁有一個可以跟蹤使用者語言喜好設定並可基於每個請求初始化地區性設定的網站。現在,我必須使用資源檔為 ASP.NET 2.0 網站本地化字串文字,以便能夠滿足使用不同語言的使用者的需求。

ASP.NET 2.0 中的資源檔

由於在預設情況下,Visual Studio 2005 不使用項目來管理 ASP.NET 2.0 網站,所以將不會存在項目層級的資源檔,就像 Windows Forms 應用程式或類庫 DLL 中那樣。相反,您必須顯式建立資源檔並將其添加到您的網站。而且,您還必須使用隨 ASP.NET 2.0 引入的特殊檔案夾:包含全域資源的資源檔應被添加到 App_GlobalResources 檔案夾,而特定於某個檔案的本地資源則應被添加到 App_LocalResources 檔案夾。全域資源就是那些來自於頁面及其他檔案(如網站圖)、可以在網站範圍基礎上使用的資源。支援本地資源的 ASP.NET 檔案類型包含頁(.aspx 檔案)、主版頁面(.master 檔案)和使用者控制項(.ascx 檔案)。

不同於 ASP.NET 2.0 的另一點是,您不必像在開發國際化的 Windows Forms 應用程式時那樣提前編譯資源。相反,ASP.NET 運行時會準時將全域和本地資源檔編譯到 DLL 中,就像 .aspx 檔案那樣。這是一種強大的功能,因為公司只需將 .resx 檔案 XCOPY 到一個 Web 生產伺服器上,即可為新語言添加本地化支援。

讓我們在使用 Visual Studio 2005 的 ASP.NET 2.0 網站中,來完成一個建立和使用全域資源檔的樣本。您可以先選擇 Add New Item(添加新項)命令,然後再選擇 Resource File(資源檔),來建立一個新的全域資源檔。

當您單擊 Add(添加)按鈕建立一個新的全域資源檔時,Visual Studio 2005 會用一個對話方塊對您進行提示,建議您將新的資源檔放置在 App_GlobalResources 目錄內。單擊 Yes(是)。如果您將其置於他處,則 ASP.NET 便不會將資源檔自動編譯到 DLL 中。

在 ASP.NET 中使用資源檔與在 Windows Forms 應用程式中相同。首先建立一個資源檔,其字串文字已本地化為預設區域性設定。在我們的樣本網站中,有一個用於該目的的全域資源檔,該檔案的名稱為 Litware.resx, 4 所示。在您添加了所有採用預設區域性設定的指定字串後,即可複製該資源檔並將其重新命名,例如重新命名為 Litware.fr.resx 以提供法語的本地化字串。您還可以複製該法語資源檔並將其重新命名為 Litware.fr-BE.resx,以維護已局部本地化為比利時法語的字串。

圖 4 本地化資源

在資源檔中添加和維護指定字串非常容易,因為 Visual Studio 2005 提供了方便易用的資源編輯器, 5 所示。請記住,資源檔並不僅限於本地化字串。您可以添加其他類型的資源,像檔案、階層式樣式表和用戶端 JavaScript 檔案。

圖 5 Visual Studio 2005 資源編輯器

現在,我們來建立從全域資源檔檢索指定字串的頁面。這做起來非常容易,就像是在開發一個國際化的 Windows Forms 應用程式時,無需直接對 .NET 提供的 ResourceManager 類進行編程。因為 ASP.NET 和 Visual Studio 2005 可以在後台為每個全域資源檔產生一個強型別化資源類,並通過 IntelliSense 使其變為可用。

可通過一個駐留在名為 Resources(資源)的頂級命名空間內的強型別化類,來訪問您添加到全域資源檔中的指定字串。它使用一行代碼,將一個本地化的字串分配給控制項的屬性值:

lblApplicationName.Text = Resources.Litware.ApplicationName

除了以編程的方式訪問外,ASP.NET 2.0 還引入聲明性文法,您可以使用它將指定的字串綁定到頁或控制項的屬性。該文法涉及使用貨幣符號 ($),其後緊跟資源命名空間、資源檔名和字串名:

<%$ Resources:Litware, ApplicationName %>

例如,如果您想將名為 ApplicationName 的字串綁定到 .aspx 頁內一個標籤的 Text 屬性,您可以像這樣編寫標記:

<asp:Label ID="lblApplicationName" runat="server"
Text="<%$ Resources:Litware, ApplicationName %>" />

Visual Studio 2005 還提供一個名為 Expression Builder 的方便易用的工具, 6 所示。該公用程式可協助您產生將資源檔中指定字串綁定到控制項或頁屬性時所需的文法。在您用指定的字串添加了一個或多個全域資源檔後,即可通過將 .aspx 頁置於設計檢視,並通過 Property(屬性)表訪問 Expressions 屬性,來訪問 Expression Builder。

圖 6 Expression Builder

請注意,聲明性資源綁定運算式不僅限於 .aspx 檔案、.ascx 檔案和 .master 檔案。也可用於本地化 Web.sitemap 檔案中定義的網站圖中的字串文字。圖 7 顯示來自 LitwareWebApp 網站中網站圖的 XML,它用於本地化該網站導覽菜單中顯示的連結標題。

使用本地資源

本地資源檔包含用於網站內基於檔案的單獨項的資源,如頁、主版頁面或使用者控制項。每個本地資源檔都必須正確命名並添加至 App_LocalResources 檔案夾,以由 ASP.NET 進行編譯。

本地資源檔的命名,應與它要為之提供資源的基於檔案的項一致。例如,包含用於 AddCustomer.aspx 頁的預設區域性資源的本地資源檔,應命名為 AddCustomer.aspx.resx。包含法語資源的本地資源檔應命名為 AddCustomer.aspx.fr.resx。

在您將指定的字串添加到本地資源檔後,即可通過三種方式從頁面或使用者控制項內訪問它們。第一,您可以通過編程方式進行訪問。第二,您可以使用顯式文法,以聲明的方式綁定到其上。第三,您可以使用隱式文法,以聲明的方式綁定到其上。下面開始逐個探討這些方法。

假設您已建立了一個本地資源檔,來本地化頁面 AddCustomer.aspx 上顯示的所有控制項標題。要本地化該頁提交按鈕上顯示的標題,您可以建立一個名為 btnSubmit.Text 的本地化字串。在將該指定字串添加到本地資源檔後,您即可通過以下調用 GetLocalResourceObject 方法和將傳回值轉換為字串的代碼來進行訪問:

'*** AddCustomer.aspx.vb 內的代碼
btnSubmit.Text = _
Me.GetLocalResourceObject("btnSubmit.Text").ToString()

此代碼不如以前顯示的代碼好,以前顯示的代碼是從使用強型別化類的全域資源訪問指定的字串。本地資源檔沒有相關聯的強型別化類,所以您無法從 IntelliSense 中獲益,而且必須在調用 GetLocalResourceObject 時,顯式地轉換基於對象的傳回值。

如果您要使用顯式聲明性綁定文法,則其使用方式與使用全域資源時大致相同。唯一不同的是您使用本地資源時,可以忽略資源檔的名稱:

<asp:Button ID="btnSubmit" runat="server"
Text="<%$ Resources:btnSubmit.Text %>" />

隱式聲明性綁定文法是功能最強大的選項。首先將名為 meta:resourcekey 的特殊屬性添加到控制標記,或添加到一個 ASP.NET 指令,如 Page、Master 或 Control。例如,如果您想通過 .aspx 檔案中的 Button(按鈕)控制項來使用隱式聲明性綁定文法,您可以像這樣編寫標記:

<asp:Button ID="btnSubmit" runat="server"
meta:resourcekey="btnSubmit" />

在您添加了 meta:resourcekey 屬性後,就只剩一件事需要考慮了,即確保本地資源檔中的字串具有正確的名稱。在我的樣本中,ASP.NET 會自動載入名為 btnSubmit.Text 的本地化字串,並將其分配給名為 btnSubmit 的控制項的 Text 屬性。

關鍵在於,隱式綁定的基礎是,建立的字串應具有與 meta:resourcekey 屬性定義的目標和屬性的名稱相匹配的名稱。本樣本中,由於 meta:resourcekey 是面向 btnSubmit 的,所以只需將更多指定的字串添加到本地資源檔中,這樣您不僅可以綁定到 Text,而且還可以綁定到其他幾個屬性值, 8 所示。

圖 8 添加指定的字串

請注意,Visual Studio 2005 可以在設計檢視編輯器中開啟頁、使用者控制項或主版頁面時,在 Tools(工具)菜單中提供一個名為 Generate Local Resource(產生本地資源)的方便易用的命令。該命令可自動建立預設區域性的本地資源檔。還可在頁面中添加 meta:resourcekey 屬性,並在本地資源檔中建立相應的字串值,來充當 meta:resourcekey 屬性項目的目標。

最後,請注意:有一個名為 Localize(本地化)控制項的 ASP.NET 2.0 新組件,可以使您本地化 .aspx 頁上的任何元素。它提供一種不由其基類提供的設計時間功能:Literal(文字)控制項;尤其是,Localize(本地化)控制項提供了靜態內容的設計時間編輯,以便您能夠在頁面設計模式下工作時查看預設值。

在 DLL 項目中嵌入資源

我將暫時撇開國際化和本地化主題,先討論一種在類庫 DLL 中使用嵌入資源的新 ASP.NET 技術。該技術允許您在 DLL 中內嵌影像檔案、階層式樣式表檔案和 JavaScript 檔案,並通過 DLL 在託管 Web 服務器上加以提供。

請注意,該技術需要使用一個面向 ASP.NET 2.0 網站的類庫 DLL。這一新功能是由 ASP.NET 團隊特別添加的,目的是為伺服器端的控制項建立者提供一種更好的方式,使他們可以在分配自訂控制項和 Web 組件的同時分配資源檔。不必將資源檔與 DLL 一起分配,也不必確保他們被複製到託管 Web 服務器上一個可訪問的路徑,資源檔現在可以在 DLL 內自行分配,並可通過運行時由 ASP.NET 產生的 URL 加以提供。

LitwareWebApp 網站包含一個名為 LitwareWebComponents 的類庫 DLL 項目,該項目示範了這一技術。在該項目內,有一個名為 LitwareSlogan.png 的影像檔已被作為資源嵌入。您可以通過將檔案的“產生操作”更改為“內嵌資源”,將資源嵌入到一個程式集中, 9 所示。

圖 9 嵌入資源

要提供對 DLL 內一個內嵌資源檔案的基於 Web 的訪問,您必須添加一個名為 WebResource 的程式集層級的屬性。當您添加 WebResource 屬性時,必須包含資源檔的限定名及其 MIME 類型。在 Visual Basic 類庫 DLL 項目中,限定資源檔名包含項目名。

'*** 在 AssemblyInfo.vb 內
Imports System.Web.UI
<Assembly: WebResource( _
"LitwareWebComponents.LitwareSlogan.png", "image/png")>

WebResource 屬性允許您為 ASP.NET 運行時提供所需的中繼資料,以通過使用可在運行時產生的 URL,從 DLL 中檢索資源檔。要從伺服器端控制項內的代碼產生資源檔的 URL,您可以調用一個名為 GetWebResourceUrl 的方法, 10 所示。

這是使該技術得以啟動並執行後台情況。一個對 GetWebResourceUrl 的調用產生一個指向名為 WebResource.axd 的內建 HTTP 處理常式的 URL。這個動態產生的 URL 還包含一個查詢字串,來識別目標 DLL 的名稱和內嵌資源檔案。通過載入一個名為 AssemblyResourceLoader 的自訂 HttpHandler 類,ASP.NET 運行時可以響應 WebResource.axd 的請求。

當調用 AssemblyResourceLoader 類以從 DLL 載入資源檔時,它可以讀取由 WebResource 屬性提供的中繼資料。AssemblyResourceLoader 類已被實現以從 DLL 的映像中提取請求資源檔,並將其引流回調用程式。AssemblyResourceLoader 類甚至提供緩衝演算法,可在它被載入到前端 Web 宿主記憶體後,在多個請求中重複使用同一資源檔。

顯示本地化映像

雖然使用內嵌資源檔案和 WebResource 屬性會具有強大的功能,但是仍然存在一些明顯的局限性。首先,您只能在面向 ASP.NET 2.0 網站的 DLL 項目內使用該技術。您無法在 ASP.NET 2.0 網站內直接使用該技術。第二,該技術實際上並不支援任何形式的本地化。如果您的網站具有諸形映像和階層式樣式表等已經本地化的資源檔,則您將不得不採用其他方法。

LitwareWebApp 網站顯示一個名為 LitwareSlogan.png 的圖形映像。該網站可依據目前使用者更喜歡英語還是法語來顯示不同版本的映像。儘管 ASP.NET 2.0 不直接支援本地化影像檔,但它也不需要過多的自訂代碼來完成所需的效果。

您可以將語言版本的影像檔添加到語言版本的全域資源檔,並以此作為開始。例如,英語版本的 LitwareSlogan.png 已被添加到名為 Litware.resx 的全域資源檔,而法語版本的 LitwareSlogan.fr.png 則已添加到 Litware.fr.resx。這兩個資源檔中的資源擁有一個相同的名稱:LitwareSlogan。

當不同語言版本的全域資源檔中含有語言版本的影像檔時,您可以使用名為 LitwareSlogan.ashx 的自訂處理常式檔案,基於使用者的語言喜好設定來有條件地進行載入, 11 所示。

LitwareSlogan.ashx 中定義的自訂處理常式類可使用您以前在自訂 InitializeCulture 方法中看到的類似邏輯,在從全域資源檔中檢索影像檔以前,初始化當前線程的 CurrentUICulture 設定。您可能會注意到,要載入正確的資源檔,您必須初始化當前線程的 CurrentUICulture 屬性,但不必初始化 CurrentCulture 屬性。

在該自訂處理常式正確初始化了 CurrentUICulture 設定之後,它即可通過 Litware.resx 的強型別化資源類來訪問影像檔。然後,便只需將影像檔的數位編寫到 HTTP 響應流。顯示本地化映像的最後步驟是,將 LitwareSlogan.ashx URL 分配到網站內任何頁面上一個影像控制的 ImageUrl 屬性。

總結

ASP.NET 2.0 使國際化網站和資源變得更加容易。通過檢查瀏覽器發送的 HTTP 標題,可在網站內輕鬆地初始化頁面的地區性設定。而且,還可輕鬆地設計更加複雜的機制,使使用者能夠通過配置所需的語言喜好設定來個人化其體驗。

請將您要提交給 Ted 的問題和意見發送至 instinct@microsoft.com。

Ted Pattison 身為作者兼培訓人員的 Ted Pattison 最近成立了 Gorilla Training,該公司致力於提供有關 SharePoint 技術的、極具實力的開發人員培訓。Ted 還在為 Microsoft Press 編寫一本名為 Inside Windows SharePoint Services 3.0 的書。

本文摘自 2006 年 8 月出版的《MSDN Magazine》。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.