摘要:VS 2010 和 .NET 4.0 系列之《ASP.NET 4 Web Forms 的整潔HTML標識 — 客戶端ID》篇
【原文位址】 Cleaner HTML Markup with ASP.NET 4 Web Forms – Client IDs (VS 2010 and .NET 4.0 Series)
【原文發表日期】 Tuesday, March 30, 2010 7:02 PM
【譯注;由於工作繁忙,三月份之後一直沒有時間翻譯Scott Guthrie的部落格。欣慰的是,新的文章已由微軟指定的專門公司做了翻譯,這裡我將補上其間沒有翻譯的一些技術文章。 –思歸】
這是我針對即將發佈的VS 2010 和 .NET 4所撰寫的 文章系列的第十六篇。
今天的文章是我將撰寫的幾個相關文章的第一篇,主要討論我們所做的一些重大變更,旨在使ASP.NET 4 的Web Forms生成整潔,與標準相相容,CSS友好的標識。今天,我將討論我們正在做的工作,以對由伺服器控制項顯示到客戶端的「ID」屬性提供更好的控制。
【除了寫部落格外,我現在還使用Twitter發短文和共享連結。請透過twitter.com/scottgu跟隨我。】
整潔,與標準相容,CSS-Friendly的標識
開發人員對ASP.NET Web Forms經常埋怨的一個東西,就是在使用伺服器控制項時,他們無法生成整潔的,CSS-Friendly 的輸出和標識。下面是一些對早期ASP.NET版本的抱怨例子:
- 對HTML中自動生成的ID屬性難以編寫JavaScript來操作和使用CSS來做樣式化。
- 某些控制項(特別是asp:menu控制項)使用了表格(table),而不是更具語意的標籤,使得樣式很醜陋。
- 一些控制項生成了行內的樣式屬性,儘管控制項上沒設定樣式屬性。
- ViewState經常是大得出奇。
ASP.NET 4對建造與標準相容的網頁提供了更好的支援, ASP.NET 4 中內建的 <asp:> 伺服器控制項現在生成乾淨了許多的標識, 支援CSS樣式化,來幫助解決上面提到的所有問題。
升級現有的ASP.NET Web Forms應用時的標識相容問題
當聽說ASP.NET 4即將提供整潔的標識時,大家常問的一個問題是,「太棒了,但我現有的應用怎麼辦?在我升級後,這些變動或改進會不會造成問題?」
為幫助確保我們不會破壞現有的ASP.NET Web Forms應用中對標識和樣式所做的假設,我們在 web.config中啟用了一個配置標記,controlRenderingCompatbilityVersion,讓你決定你是想使用新的ASP.NET 4應用預設的新的整潔標識方式呢,還是為相容起見,顯示與所使用的早期ASP.NET版本同樣的標識:
當controlRenderingCompatbilityVersion屬性設定為「3.5」時,你的應用和伺服器控制項會預設使用與VS 2008 和 .NET 3.5一樣的標識生成機制來生成輸出。當 controlRenderingCompatbilityVersion屬性設定為「4.0」 時,你的應用和伺服器控制項會嚴格遵循XHTML 1.1規格,生成整潔的客戶端ID,顯示時以語意正確為宗旨,除去不相關的行內樣式。
在使用ASP.NET 4建造的所有新的 ASP.NET Web Forms中,該屬性的預設值是4.0。使用VS 2010升級的任何以前的應用,都會被升級嚮導設定controlRenderingCompatbilityVersion為3.5,以確保向後的相容性。然後你可以選擇改變這個設定(在應用級別,或在web.config文件中局限於頁面或目錄級別),如果你決定變更頁面來使用CSS,來利用新的標識顯示機制的話。
今天的整潔標識標題: 客戶端ID
在生成的HTML元素上能夠擁有乾淨的,可預料的ID屬性是開發人員一直要求Web Forms提供的東西(象 「ctl00_ContentPlaceholder1_ListView1_ctrl0_Label1」這樣的ID值實在是不受歡迎)。能夠控制生成的ID值有助於簡化針對輸出編寫的客戶端JavaScript,簡化使用CSS對元素所做的樣式化,在大的網頁上有助於減少所生成標識的總的大小。
控制項上新的ClientIDMode屬性
ASP.NET 4在Control這個基類上支援一個新的ClientIDMode屬性。ClientIDMode屬性表示控制項在顯示時,該如何生成客戶端ID值。ClientIDMode 屬性支援4個可能的值:
- AutoID –生成與.NET 3.5一樣的輸出(為相容起見,自動生成的ID還會含有象ctrl00這樣的前置詞)
- Predictable (預設值)–除去任何「ctl00」 ID 字串,如果是列表或容器控制項,則把子控制項的ID串列起來 (例子:id="ParentControl_ChildControl")
- Static (靜態)–將ID命名控制完全交給開發人員,他們設定什麼ID值,就顯示什麼值 (例子: id="JustMyId")
- Inherit (繼承)–告訴控制項使用父容器控制項的命名行為模式
ClientIDMode屬性可以直接設定在單獨的控制項上(或在容器控制項中, 內中包含的控制項會預設繼承該設定):
或在頁面或用戶控制項層次設定(使用 <%@ Page %> 或 <%@ Control %> 指令),這樣在頁面或用戶控制項中的控制項會繼承這個設定(還可以選擇覆寫這個設定):
也可以在應用的web.config文件中設定,這樣應用中的所有頁面都會繼承這個設定(還可以選擇覆蓋這個設定):
這給予了你任意客制/覆寫命名行為的彈性。
例子:使用ClientIDMode屬性控制非列表控制項的ID
讓我們來看一下,如何使用新的ClientIDMode屬性來控制網頁中 「ID」 元素的生成。為幫助示範,我們建立了一個簡單的網頁,名為「SingleControlExample.aspx」,是基於名為「Site.Master」的母版頁的,內含單個<asp:label> 控制項,其ID為「Message」 ,該控制項是包含在名為 「MainContent」的 <asp:content>容器控制項中的:
然後在後台程式碼中,我們加了一些像下面這樣的簡單的程式碼,在執行時動態填充Label的 Text屬性:
如果我們是在 ASP.NET 3.5 中 執行該應用(或將ASP.NET 4應用配置使用了3.5顯示方式或 ClientIDMode="AutoID" 執行的話),那麼生成發送到客戶端的標識會是這樣的:
這個ID是獨特的(是好事),但因為其「ct100」前置詞,又很醜陋(是壞事)。
使用ASP.NET 4以及ClientIDMode被設定為 「Predictable」時的標識顯示
在ASP.NET 4中,伺服器控制項現在預設使用 ClientIDMode="Predictable" 來生成它們的ID。這幫助確保ID值依然是獨特的,在頁面上沒有衝突,但同時也使得ID不那麼冗長,比較可以預料。這意味著我們上面的 <asp:label> 控制項生成的標識在ASP.NET 4預設的情形下,會是這樣的:
注意「ct100」前置詞現在沒有了。因為 「Message」 控制項是內嵌在「MainContent」 容器控制項中的,在預設情形下,它的ID會被前置詞,成為 「MainContent_Message」,以避免與網頁上的其他控制項相衝突。
使用ASP.NET 4以及ClientIDMode被設定為「Static」」時的標識顯示
但有時,你不想要你的ID值被分層嵌套,而只是想顯示你設定的任何值。要啟用這個的話,你現在可以使用ClientIDMode=Static,這樣顯示的ID值會跟你在伺服端在你的控制項上設定的ID值完全一樣。這在ASP.NET 4中會導致下述標識:
這個選項現在給予你完全控制控制項發送到客戶端的ID的能力。
例子:使用ClientIDMode屬性控制資料繫結列表控制項的ID
資料繫結的列表/網格在Web Form自動生成的ID方面一直以來一直是最難使用和樣式化的。現在讓我們來看一個場景,看如何在ASP.NET 4中對使用ListView控制項生成的ID進行定制。
下面的程式碼片段是個ListView控制項的例子,顯示了一個資料繫結集合(機場)中的內容:
然後,我們在後台程式碼中編寫下述程式碼來動態繫結一個機場列表到上面的ListView上:
然後在執行時,這會預設生成象下面這樣的 <ul> 機場列表。注意,因為 ListView模板中的 <ul> 和 <li> 元素不是伺服器控制項,在標識中是不會有ID的:
給每行的項目添加客戶端ID
現在,說我們想要給輸出添加客戶端ID,這樣我們可以透過JavaScript使用程式設計手法來存取每個<li>。我們想要使得這些ID是獨特的,可預料的,以及可辨識的。
第一種做法是將模板中的每個 <li> 元素標記為伺服器控制項(給它一個runat=server屬性),並且給其一個id為「airport」:
在預設情形下,ASP.NET 4現在會生成象下面這樣整潔的ID(不生成象ctl001這樣的ID):
使用ClientIDRowSuffix屬性
我們上面的模板給每個 <li> 元素生成了獨特的ID,但假如我們想要在客戶端使用JavaScript透過程式設計手法來存取它們的話,我們也許想要使得ID包含對應的機場的Code屬性,以簡化引用。好消息是,我們可以輕鬆地達到目的,透過利用ASP.NET 4中資料繫結控制項上的ClientIDRowSuffix屬性來更好地控制單獨行元素的ID。
要實現的話,我們將在ListView控制項上設定ClientIDRowSuffix屬性為「Code」。這告訴ListView在生成ID時,使用Airport類的「Code」資料繫結屬性:
這樣,行的ID後綴不再是「1」, 「2」, 或 「3」,而是將Airport.Code值嵌合到ID中去了(例如:_CLE, _CAK, _PDX等等):
你也可以在其他資料繫結控制項(象GridView)上使用 ClientIDRowSuffix。在你想要在客戶端對行元素進行程式設計,在JavaScript程式碼中使用乾淨的/可辨識的ID來輕鬆地引用這些元素時,這會非常有用。
結語
ASP.NET 4允許伺服器控制項和你的Web Forms應用生成乾淨許多的HTML標識。
在今天的文章中,我討論了如何輕鬆地控制伺服器控制項會輸出的 Client ID 值,在未來的文章中我將會說明未來 ASP.NET 4.0 中其他的標籤強化功能。
希望對您有幫助。
Scott