本文章是由機器翻譯。

技術最前線

瀏覽 ASP.NET 4.0 — Web 表單及之後

Dino Esposito

ASP.NET 是穩定且成熟平台來建置豐富而強大 Web 應用程式,所以很難想像一組新的引人入勝的功能加到它。 但最後一個落,ASP.NET 3.5 Service Pack 1 版本,Microsoft 精簡平台的內建的 AJAX 支援,由傳送的動態資料控制項是專為地址資料輸入應用程式與資料導向的需求而設計的元件的新架構增強其產能。

平行,Microsoft 開發呼叫 ASP.NET MVC 一個全新、 替代程式設計模型。 不像傳統的 Web Form 模型,ASP.NET MVC 幫助開發人員建立根據具有廣泛的可辨識的設計模式的 Web 應用程式:在模型檢視控制程式。
今天,整體的 ASP.NET 平台是幾個不同元件所組成:Web Form、 ASP.NET MVC、 動態的資料控制項和 ASP.NET AJAX。 即將推出的 ASP.NET 4.0 平台具有相同的基礎,為最新的 3.5 SP1 版本,但它提供進一步細分在區域中的 Web Form,動態資料控制項,但不至少最後 ASP.NET AJAX。

此的文件中,我將看看的新增和改善 Web Form 模型中。 在未來的資料行,我將地址動態資料控制項平台,整個然後深入探討在 ASP.NET AJAX 的環境中開發。

一目瞭的 ASP.NET Web Form 4.0

描述的整體的 ASP.NET 4.0 平台新的關鍵字是 「 多個控制項。ASP.NET 4.0 是架構的革命性的變更都因素重建其現有。 組成,而,一起提供更多控制某些常用的功能,現有的架構的開發人員的小型變更好數。

就例如 ASP.NET 4.0 Web Form 讓開發人員更能控制 ViewState 管理,產生識別碼的資料繫結的控制項和某些範本為基礎的控制項所產生的 HTML 內容中。 在就另外您會發現新系列的隨插即用的元件不支援提供者 2009年模型在舊版的 ASP.NET 和更好地控制透過 ScriptManager 控制項外部的指令碼檔案的連結的功能。 讓我們從 ViewState 管理開始。

ViewState 更能控制

我說沒有任何新的說明在 ViewState 其中一項最具有爭議性的 ASP.NET 功能後已經平台的隨著。 太多的開發人員仍然被 convinced ViewState 是浪費頻寬和一個無法接受的負擔,為每個 ASP.NET 網頁。 幾乎相同的開發人員設定要會歡迎 ASP.NET MVC 因為的 ViewState 其完成缺乏。 最近,時教學的 ASP.NET MVC 類別,我會討論中使用者可以從一個清單,請參閱更多詳細資料選取客戶的主要/詳細案例。 如預期般,在的網頁,載入期間填入清單。 接下來,時處理選取項目變更事件,我會說明如何填入客戶的詳細資料。 但是,將 [可用的另一個選取範圍] 清單我也必須明確地重新填入它。

學生迅速記下額外的工作需要填滿在每個伺服器的動作清單。 無法這會自動填滿在 Web Form 中嗎? 也,在 ASP.NET Web Form 中您不需要的 ViewState,只是因為補充回傳透過資料繫結控制項。

在就短,ViewState 沒有只以減少您的頻寬。 快取部分網頁中控制項是內容的功能至 Web Form 模型,ViewState。 下一步],ASP.NET 基礎結構會負責讀取 ViewState,若要還原上次已知良好控制項之狀態的每個頁面中的資訊。

如廣泛已知,但也是忽略 ViewState 是選擇性功能。 ViewState 支援為開啟狀態的每一頁依預設值,但開發人員有可用來變更預設設定和它不是布林值屬性。 屬性為 [EnableViewState,在 System.Web.UI.Control 類別上定義。 請注意 System.Web.UI.Page 類別繼承自控制項類別。 就是而言,ViewState,個別控制項和網頁是一個與相同。

對於任何的 ASP.NET 頁面關閉 ViewState 無法會更容易。 將 EnableViewState 設為 false 以宣告方式或以程式設計方式在網頁的存留週期內,如下所示:

void Page_Load(object sender, EventArgs e)
{

msdn magazine
2
Cutting Edge
// Disable viewstate for the page
// and ALL of its child controls
this.EnableViewState = false;
...
}

則 EnableViewState 屬性會指出控制項是否可以快取它自己與 UI 相關的狀態。 會收到提醒在 ASP.NET 中的 [ViewState] 設定會有這表示如果父控制項上啟用了 ViewState,就無法停用在它的子控制項的任何的階層式自然。 下列程式碼上的 [文字] 方塊行為如果無效 ViewState 已啟用在頁面或容器層級:

protected void Page_Load(object sender, EventArgs e)
{
TextBox1.EnableViewState = false;
}

IsViewStateEnabled 屬性--受保護的屬性確實--報告有關控制項的 ViewState 的目前狀態。 但做了什麼此平均值的所有開發人員嗎?

如果頁面 (這是預設的設定) 上啟用了 ViewState,您會有無法將個別控制項的狀態儲存區關閉的方式。 您需要停用在頁面層級,然後 re-enable 它其中需要但也要注意它的階層性質的 ViewState 能夠一些控制它的 ASP.NET 3.5。 已啟用 ViewState 任何容器控制項將無可避免其設定下推至它的子系的清單。 此事實通往有些微的一個 paradox:相同控制項具有 IsViewStateEnabled 設為 True,則在屬性和屬性 EnableViewState 設為 False,則可能會!

ViewState 是基本的 ASP.NET Web Form 架構,也完全從平台的效能增益的名稱將它卸除可說沒有最佳的選項。 年的經驗有一個更永續型的選項有在頁面預設停用 ViewState 證明的。 更好的不使用 ASP.NET 4.0 隨後變更:啟用個別控制項的 ViewState 控制。
在 ASP.NET 4.0,System.Web.UI.Control 類別會公開一個名為 ViewStateMode 的新屬性:

public virtual ViewStateMode ViewStateMode { get; set; }

屬性會使用其可行的值,的圖 1 所示將 ViewStateMode 列舉型別。

若要保留相容性,屬性的預設值會是繼承。 但是,這個屬性提供開發人員控制 ViewState 設定無論任何父頁面或容器的 ViewState 選項的個別控制項的可能性。

只有少數 ASP.NET 網頁中控制項的真正需要 ViewState。 就例如只收集文字要使用的所有文字方塊不在所有需要 ViewState。 如果文字您在控制項使用 [唯一] 屬性然後文字屬性的值會被保留的跨網頁回傳因為的已張貼的值。 儲存在 ViewState 中, 任何值中就實際上會被定期所覆寫已張貼的值。 在這種情況下,ViewState 就是真的不必要。 但還有更多注意到。 設定指定的非預設值,在建立,但維持不變 (例如唯讀、 背景色彩和等等),回傳期間的任何側邊內容不需要移至 ViewState。 就例如 Button 控制項,會一直保留相同的標題不都需要 ViewState。 ASP.NET 4.0,之前關閉 ViewState 個別控制項是有問題。 在下一版中,變更項目。 這是 ViewStateMode 屬性的索引鍵的 takeaway。

自動產生識別碼的進一步控制

在 ASP.NET 的網頁中不允許兩個伺服器控制項使用相同的 ID。 如果這樣,將無法編譯頁面--期間。 在 HTML,但是,很可能的兩個或多個項目共用相同的識別碼。 在這種情況下當您搜尋的項目透過 document.getElementById 時,您將只會 DOM 元素的陣列。 巢狀的 ASP.NET 控制項呢?

大部分的資料繫結、 範本為主控制項產生其輸出 HTML 範本重複每個資料繫結項目。 這表示使用唯一的 ID 在範本中定義的任何子控制項被重複多次。 原始的 ID 就不能是唯一的。 這個原因開始後,ASP.NET 團隊定義的演算法,以確保 ASP.NET 控制項所發出的每個 HTML 項目可以為指定唯一的識別碼。 識別碼產生識別碼為命名容器的控制項 ID 的串連。 此外,重複的控制項 (亦即,範本) 的情況下數值索引已加入的澄清。 多年來,沒有人真的 cared 相關的 「 自動產生的識別碼,可讀性,並如下所示字串變得相當常見:

ctl00$ContentPlaceHolder1$GridView11$TextBox1

查看這,可能會注意到有第一個問題是可能會針對數個的項目重複字串的長度會下載較大。 更是以重要這種方法是從用戶端指令碼的觀點來看有問題。 預測特定控制項,您從用戶端要編寫指令碼的 ID 困難,並會導致直接讀取硬碟的程式碼。 首先,您必須知道詳細就埋在格線或任何其他命名的容器控制項的 folds 指定 HTML 項目所產生的名稱。 第二個,此名稱有可能變更為您重新命名其中一個伺服器控制項階層架構以及。 下列是經常使用的技巧:

var btn = document.getElementById("<% =Button1.ClientID %>");

若要在產生真實用戶端識別碼指定控制項的 [HTML 程式碼中插入使用 ASP.NET 程式碼區塊中,包含可行。 當使用時主版頁面] 或 [範本為基礎的控制項可行會是真實的 lifesaver,因為一般控制項的命名容器在這種情況下最後被相當複雜的階層架構的開發人員通常保留未命名控制項。 控制的實際名稱因此,受限於少數自動產生的 ID 中。

除了使用 [程式碼區塊 ASP.NET 4.0 支援另一個選項:更多的控制演算法會產生一個伺服器控制項的用戶端 ID。

System.Web.UI.Control 類別現在提供一個名為 ClientIDMode 全新的屬性。 此屬性可以假定為 的圖 2所述幾個預先定義的值。

無可否認地,的識別碼產生演算法特別是當牽涉到主版頁面並不容易瞭解。 它會保證產生唯一的識別碼],但結束向上字串時,很難預測。 是一個可預測的選項已被引入主要是要用於資料繫結控制項,讓開發人員可以輕鬆地猜出的說,Label 控制項用來呈現第 n 個資料項目上指定的內容 ID。 在此情況下,您會想以反映該控制項 (簡化命名容器結構至父控制項),但也特定的機碼值,例如主索引鍵的階層識別碼。 請考慮下列程式碼:

<asp:GridView ID="GridView1" runat="server"
ClientIDMode="Predictable"
RowClientIdSuffix="CustomerID">
...
</asp:GridView>

在這種情況下於格線的每個資料列會識別一或多個資料來源中的資料行以結尾的索引。 以下為範例:

Panel1_GridView1_ALFKI_1

GridView 唯一控制項來支援多個資料行中取得。 如果您要串連的多個資料行則使用逗號來分隔名稱。 清單檢視將會接受只有一個資料行,而 Repeater 控制項將會限制軌跡是以 0 為基礎的索引,並接受沒有資料行名稱。

最後,請注意 [ClientIDMode 屬性會影響只 ID 屬性產生的 HTML 項目。 設計,維持不變名稱屬性。

檢視控制限制

大部分的資料繫結控制項提供能夠選取指定的顯示的元素--大部份資料列。 在舊版 ASP.NET 中,選取項目儲存為網頁中,選取項目的索引。 這個方法可分頁的控制項 (例如 GridView 控制項),相同上, 所做的選取範圍說,除非您以程式設計的方式重設期間頁/變更選取範圍,其中一個會保留在兩個頁面的網頁事件。

在 ASP.NET 4.0,資料繫結控制項上的目前選取範圍您透過 DataKeyNames 屬性表示在資料索引鍵欄位值透過追蹤。 若要啟用這項功能,您可以使用新的 PersistSelection 布林值屬性,然後將它設定為 true。 預設值是 false,相容性的理由。

在就另外 FormView 和清單檢視控制項提供一些更好控制其產生的 HTML 標記。 在就特別 [FormView 現在全新 RenderTable 布林值屬性的帳戶。 如果設定則為 False (預設值為 true) 到再沒有額外 HTML 表格標籤將會被發出,而且整體的標記會更容易地透過 CSS 的樣式。 ListView 不再需要在 ASP.NET 4.0 中的版面配置範本:

<asp:ListView ID="ListView1" runat="server">
<ItemTemplate>
<% Eval("CompanyName")%>
<hr />
</ItemTemplate>
</asp:ListView>

上述程式碼片段,即足以對資料來源中每個項目重複 [供應商] 欄的內容。

HTML 的增強功能

在開始,ASP.NET 未提供所有可能的標籤,在 Web 網頁的多程式設計控制。 一段很長的時間的網頁標題會遺失 Page 類別上的臨機操作的屬性。 相同可以說其他常用的功能類似 CSS 檔案。

在 ASP.NET 4.0,Page 類別會公開兩個新的字串屬性可讓您集中 < 標頭 > 的一些常見的標籤網頁的區段。 兩個新屬性是 [關鍵字] 及 [說明]。 這些伺服器] 屬性的內容將會取代您可能已經指定 metatags 為 HTML 常值的任何內容。

描述與關鍵字也可以直接以這個 @ Page 指示詞的下列範例中的屬性設定屬性:

<%@ Page Language="C#"
AutoEventWireup="true"
CodeFile="Default.aspx.cs"
Inherits="_Default"
Keywords="ASP.NET, AJAX, 4.0"
Description="ASP.NET 4.0 Web Forms" %>

在 ASP.NET 中,當您叫用 Response.Redirect,您傳回瀏覽器的 HTTP 302] 程式碼表示要求的內容已提供可以從另一個 (指定) 的位置。根據的瀏覽器會將第二個要求對指定的位址,並就是這麼簡單。搜尋引擎造訪您的網頁,不過,實際上需要 HTTP 302 程式碼。這是在實際表示之 HTTP 302 狀態碼,因為要求的網頁已經暫時移至新的地址。結果搜尋引擎不會更新其內部的表格,並當使用者按一下以查看您的網頁,引擎會傳回原始的地址。接下來,瀏覽器取得的 HTTP 302 程式碼,並提出第二個要求最後顯示想要的網頁。

若要平滑整個程序,您可以利用一個全新的 ASP.NET 4.0 中將重新導向呼叫 RedirectPermanent 的方法。不同之處在於這一次呼叫端接收的 HTTP 301 狀態碼,您可以使用相同的方式使用傳統的 Response.Redirect 的方法。301 的程式碼實際上表示已永久移動要求的內容。在的瀏覽器的會不大的差異,但是搜尋引擎的主要差異。

搜尋引擎會知道如何處理的 HTTP 301 程式碼,並使用該資訊來更新網頁的 URL 參考。下一次顯示搜尋結果,包括頁面,連結的 URL 是新。以此方式使用者可以快速到頁面,並儲存自己第二個的往返作業。

輸出快取更多的控制

在 ASP.NET 2.0 中的 ASP.NET 執行階段的幾個主要部分已重整,而且做更有彈性且可設定。這被達成透過提供者模型的簡介。包括工作階段狀態、 成員資格和角色管理,某些 ASP.NET 核心服務的功能已區隔要排序的服務合約,使指定服務的不同實作可以交換使用系統管理員可能表示他們希望從組態檔的一。

就例如舊忠實的工作階段物件底下,還有 HttpSessionState 類別擷取其內容,是選取工作階段狀態提供者的執行個體。預設的工作階段狀態提供者 (特別是,從快取字典內位置),同處理序記憶體中取得資料,但其他提供者存在儲存資料庫和外部主機處理程序中的資料。

在 ASP.NET 4.0,提供者模型會包含另一個非常重要,因某些原因而被留在先前版本的 ASP.NET 功能:輸出快取。

有許多情況,是可以接受的頁面回應是有點過時的只要這帶來顯著的效能優點。想像的電子商務應用程式和它的產品類別目錄,頁一組,例如。這些分頁是相當昂貴的建立,因為它們可能需要一或多個資料庫呼叫,而且可能某種形式的資料連接。產品網頁傾向於維持不變的週數,且很少會更新每日一次以上。重新為何應該產生相同的頁面是幾百次,每秒?可從 ASP.NET 1.0,輸出快取讓您將快取頁面回應以便傳回而不是執行頁面的輸出快取可以滿足下列要求。圖 3 說明包括的步驟系統嘗試解決尋找到輸出快取要求的應用程式事件的順序。

現在,之前 (這樣可以根據表單來分組,並查詢要求 URL,] 或 [自訂字串的字串參數) 的任何網頁輸出會儲存在 ASP.NET 快取的私用區域內的記憶體中。在長期,輸出快取的數量將額外的壓力在 Web 伺服器電腦上耗用記憶體,並產生經常更新快取物件上。在 ASP.NET 4.0,輸出快取子系統完全支援提供者模型中,因此讓開發人員儲存提供 ASP.NET 背景工作 process.A 自訂輸出快取者以外的頁面回應的機會是衍生自 OutputCacheProvider 類別。必須在組態檔,註冊類別的名稱,如下所示:

<caching>
<outputCache defaultProvider="AspNetInternalProvider">
<providers>
<add name="DiskCacheProvider"
type="Samples.DiskCacheProvider, MyProvider"/>
</providers>
</outputCache>
</caching>

像往常一樣可以有多個註冊的提供者,並選取預設值透過 defaultProvider 屬性 outputCache 節點上。 預設的行為是透過 AspNetInternalProvider 物件,原來是預設的提供者,如果您不變更任何組態檔中提供。

輸出快取提供者不一定要相同的所有網頁。 您可以選擇以每個要求為基礎或甚至特定的使用者控制項、 頁面或頁面的參數組合的不同提供者。 這個指示詞 (頁面及/或使用者控制項) 會被接受的地方,您可以在 @ OutputCache 指示詞中指定提供者的名稱:

<% @OutputCache Duration="3600"
VaryByParam="None"
providerName="DiskCache" %>

若要將每個要求為基礎提供者而,您必須覆寫在 global.asax,新的方法如下所示:

{
// Decide which provider to use looking at the request
string providerName = ...;
return providerName;
}

以 2.0 版開始,可儲存工作階段狀態以外的背景工作處理序記憶體。 這表示程序的環境與儲存在工作階段物件中的任何資料必須進行序列化。 如果您查看回的圖 3 ,工作階段狀態會載入工作階段物件周圍 AcquireRequestState 的應用程式事件。 記憶體中的內容然後序列化回至結尾的要求處理的儲存體。
ASP.NET 4.0 讓開發人員要求一些壓縮来套用至資料流傳送進出工作階段提供者 (請參閱的圖 4)。 壓縮被取得要任何的序列化,而非一般的資料流類別使用 GZipStream 類別:

<sessionState mode="SqlServer" compressionEnabled="true" ... />

若要線上啟用壓縮您只要新增 compressionEnabled 屬性到工作階段狀態組態檔的區段。 預設情況下,不會啟用壓縮。

任何 JavaScript 程式庫是由組成各種特定的 JavaScript 檔案與 interconnections 的更多或更少的複雜圖形。 ASP.NET AJAX,而,永遠嘗試抽象 JavaScript 詳細資料,從開發人員,而整合型的用戶端 JavaScript 程式庫透過 ScriptManager 控制項。 這會在 ASP.NET 4.0 中進行變更。 Microsoft 的 AJAX 用戶端程式庫已被重整,而且分割成個別的檔案的圖 5 所示。 圖 6 顯示整體程式庫中的個別指令碼檔案之間的相依性。

新的屬性已新增至 ScriptManager 控制項,可讓您指定應如何處理文件庫的建置區塊。 屬性 MicrosoftAjaxMode,並圖 7 所示,它會接受值。

更好的平台

ASP.NET 4.0 Web Form 包含許多小型變更的一起,使其更好的開發平台。 Web Form 是一種成熟的架構需要細分,不重新設計的。 如果您不覺得完全熟悉 Web Form,並尋找完全不同的 ASP.NET MVC 值得注意看。

Dino Esposito 是架構設計人員在 IDesign 和 co-author 的 「 Microsoft.NET:企業的架構的應用程式"(Microsoft 按,2008年)。 根據在義大利,Esposito 是經常在世界各地的產業活動演講者簡報。 您可以在 weblogs.asp.net/despos 加入他的部落格。