天天看點

【轉】了解使用 ASP.NET AJAX 進行局部頁面更新

簡介

Microsoft的 ASP.NET 技術提供了一個面向對象、事件驅動的程式設計模型,并将其與已編譯代碼的優勢結合起來。但其伺服器端的處理模型仍存在技術本身所固有的幾點不足:

進行頁面更新需要往返伺服器,是以需要頁面重新整理;

來回往返不會保留 Javascript 或其他用戶端技術(如 Adobe Flash)生成的任何效果。

在回傳過程中,除 Microsoft Internet Explorer 之外的浏覽器都不支援自動存儲滾動位置。而即使在Internet Explorer 中,頁面重新整理時仍然會出現閃屏現象。

回傳可能會導緻占用較多的帶寬,這是因為 __VIEWSTATE 表單字段可能會變大,尤其是在處理 GridView 或 Repeater 等控件時。

沒有統一的模型用于通過JavaScript或其他用戶端技術通路 Web 服務。

進入 Microsoft 的 ASP.NET AJAX 擴充。AJAX 的全稱為 Asynchronous JavaScript And XML(異步 JavaScript 和XML),它是一個內建架構,用于通過跨平台的JavaScript 提供增量頁面更新。AJAX 包括含有Microsoft AJAX Framework的伺服器側代碼,以及一個名為 Microsoft AJAX Script Library 的腳本元件。ASP.NET AJAX 擴充還跨平台支援通過JavaScript 通路ASP.NET Web 服務。

本白皮書将深入探讨 ASP.NET AJAX Extensions的局部頁面更新功能,包括ScriptManager 元件、UpdatePanel 控件及UpdateProgress控件,以及适合及不适合應用它們的場景。

本白皮書基于 Visual Studio 2008的Beta 2 版本和.NET Framework 3.5。.NET Framework 3.5将ASP.NET AJAX Extensions內建到了基礎類庫中(之前它是 ASP.NET 2.0 的一個插件元件)。本白皮書還假定您使用的是Visual Studio 2008 而非Visual Web Developer Express Edition。因為本教程引用的某些項目模闆對于Visual Web Developer Express 使用者可能是不可用的。

局部頁面更新

能夠進行局部或增量頁面更新,而無需執行向伺服器的完全回傳,也無需更改代碼,隻需要做很少的标記更改。這可能算得上ASP.NET AJAX Extensions 最顯而易見的特性了。其優勢有很多:不會改變您的多媒體狀态(如Adobe Flash 或 Windows Media,減少了帶寬成本,且用戶端也不會出現通常與回傳有關的閃屏現象。

局部頁面解析功能被內建到ASP.NET 中,并對您的項目做到最小程度的更改。

演練:将局部解析內建到現有項目中

在 Microsoft Visual Studio 2008 中建立一個 ASP.NET Web Site項目:打開 File –> New –> Web Site…,在對話框中選擇 ASP.NET Web Site。您自己為項目命名,Location選擇“檔案系統”或者IIS 都可以。

這時會出現一個空白預設頁面,以及基本 ASP.NET 标記(一個伺服器側表單以及一個@Page指令)。在頁面的表單元素中,添加一個名為 Label1的 Label 以及一個名為 Button1的 Button。您可自行設定它們的文本屬性。

在設計視圖中輕按兩下 Button1以生成一個代碼檔案 event handler。在此 event handler 中将 Label1.Text設為 "You clicked the button!"。

程式清單1:啟用局部解析之前 default.aspx的标記

程式清單2:default.aspx.cs中的代碼檔案

按下 F5 打開您的網站。Visual Studio 将提示您添加一個 web.config 檔案以啟用調試。照此提示操作。注意當您單擊按鈕時,頁面将重新整理以更改标簽中的文本,重新整理頁面時會出現短暫的閃屏現象。

關閉浏覽器視窗後,傳回 Visual Studio 和标記頁面。在 Visual Studio 工具箱中向下滾動,找到标記為AJAX Extensions 的頁籤。(如果由于您使用的是AJAX 或 Atlas 擴充的早期版本而沒有此頁籤,請參考本白皮書稍後部分中關于注冊AJAX Extensions 工具箱項的過程的内容,或使用網絡上可下載下傳的Windows Installer 安裝新版本。

已知問題:如果您的計算機上已經安裝了帶有ASP.NET 2.0 AJAX Extensions 的 Visual Studio 2005,那麼當您安裝 Visual Studio 2008 Beta 2時,Visual Studio 2008将導入 AJAX Extensions工具箱項。您可以檢視元件的工具提示來确定自己計算機上的軟體版本,版本應為Version 3.5.0.0。如果顯示版本為 Version 2.0.0.0,說明您已經導入了原有的工具箱項,并且需要使用Visual Studio 的 Choose Toolbox Items 對話框來手動導入。不能通過設計器添加Version 2 控件。

在 <asp:Label>标記開始之前,建立一個空白行,并輕按兩下工具箱中的 UpdatePanel 控件。注意,頁面頂部包含了一個新的@Register 指令,表示應使用 asp:prefix 導入 System.Web.UI 命名空間中的控件。

将 </asp:UpdatePanel>結束标記拖過 Button元素的末尾,以使元素有效包裝 Label和 Button控件。

在<asp:UpdatePanel>标記之後添加一個新标記。注意,IntelliSense 将提示有兩個選項。此處請選擇建立<ContentTemplate> 标記。確定用此标記包括您的Label 和 Button控件,以使标記有效。

在 <form>元素中的任何位置,輕按兩下工具箱中的 ScriptManager項,以包含一個 ScriptManager 項。

編輯 <asp:ScriptManager>标記以使其包含 EnablePartialRendering=”true”屬性。

程式清單3:啟用局部解析的default.aspx的标記

打開 web.config 檔案。注意,Visual Studio 自動添加了一個指向 System.Web.Extensions.dll的編譯引用。

Visual Studio 2008 的新特性:ASP.NET 網站項目模闆附帶的 web.config 自動包含了所有必需的到ASP.NET AJAX Extensions 的引用,且包含配置資訊中可删除注釋以啟用附加功能的加注釋部分。在安裝了ASP.NET 2.0 AJAX Extensions後,Visual Studio 2005 也擁有相似的模闆。但在 Visual Studio 2008 中,AJAX Extensions 預設是被引用的,但是可以選擇其不被引用。

按下 F5 啟動您的網站。注意,對局部解析的支援并不要求進行任何源代碼更改,隻更改标記。

啟動您的網站時,應該看見現在已經啟用了局部解析。因為您單擊按鈕時沒有出現閃屏現象,頁面的滾動位置也沒有更改(示例并未說明這點)。如果您要在單擊按鈕後檢視頁面的被解析過的源代碼檔案,将可以确認實際上沒有産生回傳:原有的标簽文本仍是源标記的一部分,标簽是通過JavaScript 更改的。

Visual Studio 2008 Beta 2并沒有自帶ASP.NET AJAX-Enabled網站模闆。但是在Visual Studio 2005中提供了這樣的模闆,當然,前提條件是你安裝了 Visual Studio 2005和ASP.NET 2.0 AJAX Extensions。是以,配置網站和從 AJAX-Enabled Web Site 模闆開始似乎要簡單一些,因為模闆預設包含一個經過完全配置的web.config 檔案(支援所有 ASP.NET AJAX Extensions,包括Web 服務通路和 JSON 序列化:JavaScript Object Notation),且Web 表單首頁面中包含一個 UpdatePanel 和 ContentTemplate。為這樣一個預設頁面啟用局部解析非常簡單,隻需要重新執行本過程的步驟10 并将需要的空間拖拽到頁面中即可。

ScriptManager 控件ScriptManager 控件引用

啟用标記的屬性:

屬性名稱

類型

說明

AllowCustomErrors-Redirect

Bool

指定是否使用 web.config 檔案的定制錯誤部分來處理錯誤。

AsyncPostBackError-Message

String

傳回或設定在出現錯誤時向用戶端發送的錯誤消息。

AsyncPostBack-Timeout

Int32

傳回或設定用戶端應等待異步請求完成的預設時間。

EnableScript-Globalization

傳回或設定是否啟用腳本全球化。

EnableScript-Localization

傳回或設定是否啟用腳本本地化。

ScriptLoadTimeout

确定向用戶端載入腳本允許的秒數。

ScriptMode

Enum (Auto, Debug, Release, Inherit)

傳回或設定是否呈現腳本的版本号。

ScriptPath

傳回或設定要向用戶端發送的腳本檔案的位置的根路徑。

隻用代碼實作的屬性:

AuthenticationService

AuthenticationService-Manager

傳回關于要向用戶端發送的ASP.NET Authentication Service 代理的詳細資訊。

IsDebuggingEnabled

傳回是否啟用代碼調試。

IsInAsyncPostback

傳回關于頁面目前是否處于異步回傳請求狀态的資訊。

ProfileService

ProfileService-Manager

傳回關于要向用戶端發送的ASP.NET配置檔案服務代理的詳細資訊。

Scripts

Collection<Script-Reference>

傳回一個要向用戶端發送的腳本引用集合。

Services

Collection<Service-Reference>

傳回一個要向用戶端發送的Web伺服器代理引用的集合。

SupportsPartialRendering

傳回關于目前用戶端是否支援局部解析的資訊。如果屬性傳回false,那麼所有頁面請求都是标準回傳。

公共代碼方法:

方法名稱

SetFocus(string)

Void

将用戶端在請求完成時的焦點設定為某個特定控件。

标記子項:

标簽

<AuthenticationService>

提供關于代理 ASP.NET 驗證服務的詳細資訊。

<ProfileService>

提供關于代理ASP.NET 配置檔案服務的詳細資訊。

<Scripts>

提供額外的腳本引用。

<asp:ScriptReference>

表示某個特定的腳本引用。

<Service>

提供将有代理類生成的額外的Web服務引用。

<asp:ServiceReference>

表示某個特定的 Web 服務引用。

ScriptManager 控件是 ASP.NET AJAX Extensions根本核心。它提供對腳本庫(包括大量用戶端腳本類型系統)、支援局部解析的通路、并提供支援大量額外的ASP.NET 服務(如驗證和配置檔案服務,以及其他Web 服務)。此外,ScriptManager 控件還提供隊用戶端腳本的全球化和本地化支援。

提供變更和補充腳本

由于 Microsoft ASP.NET 2.0 AJAX Extensions 的調試版本和釋出版本都在引用程式集中嵌入了完整的腳本代碼,開發者可以随意重定向ScriptManager 到定制腳本檔案,或是注冊所需的其他腳本。

通過注冊 ScriptManager 類的ResolveScriptReference事件,可以覆寫正常包含的腳本(如支援 Sys.WebForms 命名空間及定制分類系統)的預設綁定關系。此方法被調用時,event handler 可以更改指向相關腳本檔案的路徑。然後腳本管理器将向用戶端發送一個其他或定制的副本。

此外,可以通過編碼或通過标記包含腳本引用(以ScriptReference類表示)。操作方法為:通過編碼更改ScriptManager.Scripts 集合,或将 <asp:ScriptReference>标記插入 <Scripts> 标記下方。<Scripts> 标記是 ScriptManager 控件的一級子标記。

定制 UpdatePanels 的錯誤處理

更新是通過由 UpdatePanel 控件指定的觸發器處理的。但對錯誤處理和定制錯誤消息的支援則是由頁面的ScriptManager 控件執行個體處理的。它通過将一個AsyncPostBackError事件暴露到稍後将提供定制異常處理邏輯的頁面中來實作。

您可以通過使用AsyncPostBackError事件指定AsyncPostBackErrorMessage屬性,然後将觸發一個警告框,使其在回調結束時顯示。

如果不使用預設的警告框,可以在用戶端進行定制。例如,您可能想要顯示一個定制的<div> 元素,而不是預設的浏覽器模式對話框,這樣就可在用戶端腳本中處理錯誤。

程式清單 5:顯示定制錯誤的用戶端腳本

上述腳本隻是向用戶端 AJAX 運作時注冊了一個回調,要求傳回異步請求完成的時間。然後檢查是否報告了任何錯誤。如果有,處理錯誤的詳細資訊,并最終向運作時顯示錯誤已在定制腳本中解決。

全球化和本地化支援

ScriptManager 控件提供了廣泛的腳本字元串和使用者界面元件的本地化支援,但這些内容不在本白皮書範圍之内。更多資訊請參見《ASP.NET AJAX Extensions 的全球化支援》白皮書。

UpdatePanel 控件UpdatePanel 控件引用

ChildrenAsTriggers

bool

指定子控件是否根據回傳自動調用重新整理。

RenderMode

enum (Block, Inline)

指定将内容顯示為可見的方式。

UpdateMode

enum (Always, Conditional)

指定是否總是在局部解析時重新整理UpdatePanel,還是隻在觸發器被觸發時重新整理。

IsInPartialRendering

傳回 UpdatePanel 是否為目前請求支援局部解析。

ContentTemplate

ITemplate

傳回更新請求的标記模闆。

ContentTemplateContainer

Control

傳回更新請求的程式設計模闆。

Triggers

UpdatePanel-

TriggerCollection

傳回與目前 UpdatePanel 關聯的觸發器的清單。

Update()   

Void   

通過編碼更新指定 UpdatePanel。允許某個伺服器請求觸發某個未通過其他方式觸發UpdatePanel的局部解析。

<ContentTemplate>

指定要用于呈現局部解析結果的标記。 <asp:UpdatePanel> 的子元素。

<Triggers>

指定一個包含 n 個與更新此 UpdatePanel 關聯的控件的集合。<asp:UpdatePanel>的子元素。

<asp:AsyncPostBackTrigger>

指定調用特定UpdatePanel 的局部頁面呈現的觸發器。該觸發器可能是有問題的UpdatePanel的一個子代控件,也可能不是。精确到事件的<Triggers>的 name.Child。

<asp:PostBackTrigger>

指定一個引發整個頁面更新的控件。該控件可能是有問題的UpdatePanel的一個子代控件,也可能不是。精确到事件的<Triggers>的 object.Child。

UpdatePanel控件用于分隔伺服器端的将參與AJAX Extensions 的局部解析功能的内容。一個頁面上的 UpdatePanel 控件數量沒有限制,而且也可以嵌套。每個 UpdatePanel 都是孤立的,以便都能獨立工作(您可以同時運作兩個UpdatePanel,解析頁面的不同部分,與頁面的回傳無關)。

UpdatePanel 控件主要用于處理控件觸發器:在預設情況下,UpdatePanel 的 ContentTemplate包含的任何建立回傳的控件都注冊為UpdatePanel的一個觸發器。也就是說,UpdatePanel 可以與預設的資料綁定控件(如GridView)一起運作,也可以在腳本中通過程式設計實作。

預設情況下,當觸發一個局部頁面解析時,頁面上的所有 UpdatePanel 都将重新整理,而不論這些UpdatePanel 控件是否定義了此動作的觸發器。例如,如果某個UpdatePanel 定義了一個 Button 控件,那麼單擊此 Button 控件時,該頁面上的所有UpdatePanel 控件都将被預設重新整理。這是因為UpdatePanel 的 UpdateMode 屬性被預設設為 Always。您也可以将 UpdateMode 的屬性改為 Conditional,這樣 UpdatePanel 将隻在觸發特定觸發器時才會被重新整理。

定制控件注釋

可以向任何使用者控件或定制控件添加 UpdatePanel。但這些控件所在的頁面必須包含一個 ScriptManager 控件,且其EnablePartialRendering屬性被設為 true。

使用 Web Custom Controls時,添加UpdatePanel 的一個方法就是覆寫CompositeControl類的受保護的 CreateChildControls()方法。這樣,如果您确定頁面支援局部解析,就可以向控件的子控件和外部之間插入一個UpdatePanel;否則,您可以直接将子控件放入一個容器Control 執行個體中。

UpdatePanel 注意事項

UpdatePanel 的運作類似于一個黑匣子,它在 JavaScript XMLHttpRequest的内部将 ASP.NET 回傳進行包裝。但其在行為和速度方面的性能都有一些重要事項需要牢記于心。要了解UpdatePanel 的原理以便能從最佳的角度決定其使用,就應檢查AJAX 交換。下面的示例使用一個現有的網站以及安裝了Firebug 擴充的 Mozilla Firefox (Firebug 擷取 XMLHttpRequest 資料)。

試想在一個表單中,除了其他元素還有一個郵政編碼文本框,用于填充表單或控件上的城市和國家字段。此表單最後将收內建員資訊,包括使用者的姓名、位址及聯系方式。根據特定項目的不同要求,設計時有多個事項需要考慮。

在該應用的原疊代中,建立了一個控件,包含完整的使用者注冊資料,其中就有郵政編碼、城市和國家資訊。整個控件都包裝在一個UpdatePanel 中,并被拖放到一個 Web 表單上。使用者輸入郵政編碼時,UpdatePanel 檢測到事件(後端對應的TextChanged 事件,通過指定觸發器或使用設為true 的ChildrenAsTriggers 屬性實作)。AJAX 将所有字段放入 UpdatePanel,這些字段就是 FireBug 擷取的資料(參見右面的圖示)。

如螢幕截圖所示,UpdatePanel中每個控件的值以及ViewState字段都被傳遞了(本例中都為空)。發送的資料總共有9kb,而産生此特定請求需要的資料隻有5 位元組。而響應則更大:總共有57kb 發送到用戶端,作用僅是更新一個文本字段和一個下拉字段。

來看看 ASP.NET AJAX 如何更新顯示也許很有意思。UpdatePanel 的更新請求的響應部分是在左面的 Firebug 控制台顯示上顯示的。這是一個專門生成、用豎線分隔的字元串,由用戶端腳本打亂順序,然後在頁面上重新組合起來。ASP.NET AJAX 特地在表示您的 UpdatePanel 的用戶端上設定 HTML 元素的 innerHTML 屬性。由于浏覽器要重新生成DOM,将會有短暫延遲,時間根據需要處理的資訊量而定。

重新生成 DOM 将觸發多個其他事件:

如果焦點 HTML 元素是在 UpdatePanel 中的,将成為非焦點元素。是以,按下Tab 鍵以退出郵政編碼文本框的使用者,接下來将進入City 文本框。但一旦 UpdatePanel 重新整理了顯示,表單就不會有焦點,按下Tab 鍵将開始突出顯示焦點元素(如連結)。

如果有任何類型的定制用戶端腳本處于使用中,且使用過程需要通路 DOM 元素,那麼功能所儲存的引用可能在局部回傳後消失。

UpdatePanel 并不是能解決一切問題的辦法。它們隻是為特定情況提供快速解決方案,包括模組化、小控件更新等,并為熟悉.NET 對象模型但不熟悉DOM 的ASP.NET 開發者提供一個熟悉的界面。根據不同的應用場景,有多種辦法可用于提升性能:

如果開發者考慮使用 PageMethods 和 JSON (JavaScript 對象注解),可以如同調用 Web 服務一樣在頁面上調用靜态方法。由于這些方法是靜态的,是以不需要狀态。腳本調用程式提供參數,将傳回異步結果。

如果需要在同一個應用程式的多個不同位置使用某一個控件,則考慮使用一個 Web 服務和 JSON。這也需要少量的額外工作,且是異步運作的。

通過 Web 服務或頁面方法內建功能也有其缺點。首先最重要的是,ASP.NET 開發者通常傾向于在使用者控件(.ascx files)中建立小的功能元件。頁面方法不能包含在這些檔案中,隻能包含在實際的.aspx 頁面類中。而與此相似,Web 服務也必須包含在 .asmx 類中。根據應用程式不同,這種體系結構可能與單個職責原則相沖突。因為單個元件的功能現在跨越了聯系很小甚至沒有的兩個或多個實體元件。

最後,如果應用程式要求使用UpdatePanel,下面這些原則将有助于故障排除和維護。

盡量不嵌套UpdatePanel,不論是在代碼單元内部嵌套或跨代碼單元嵌套都應避免。例如,頁面上有一個包裝了一個Control 的 UpdatePanel,而此 Control 也包含一個 UpdatePanel,後者又包含另一個 Control,此 Control 又包含 一個 UpdatePanel,則是跨單元嵌套。這将有助于搞清楚哪些元素應被重新整理,避免出現對子UpdatePanel 的意外重新整理。

保持ChildrenAsTriggers屬性設為false,且明确設定觸發事件。利用 <Triggers>集合可以更清楚地處理事件,且能避免不必要的操作,進而有助于維護任務的執行,且促使開發者“決定參與”某個事件。

盡可能使用最小的單元來實作功能。正如郵政編碼服務示例中的讨論所示,隻包裝最少的内容可以減少到伺服器的時間、總處理以及占用的用戶端-伺服器交換,進而提升性能。

UpdateProgress控件UpdateProgress控件引用

标記啟用的屬性:

AssociatedUpdate-PanelID

指定此 UpdateProgress應對其報告的 UpdatePanel 的 ID。

DisplayAfter

Int

指定在異步請求開始後到顯示控件前的逾時毫秒數。

DynamicLayout

指定是否動态呈現進度。

子代标記:

<ProgressTemplate>

包含将用此控件顯示的内容的控件模闆集。

UpdateProgress控件可用于進行回報,以便在向伺服器傳輸時保持使用者的興趣。它可以幫助您的使用者知道您正在執行某項操作,這項操作甚至會是不太直覺的。在大多數使用者已經習慣了頁面更新和檢視狀态欄高亮顯示的情況下,這尤其有用。

注意,UpdateProgress控件可以在頁面層級結構中的任何位置顯示。但如果局部回傳是從某個子 UpdatePanel (嵌套在另一個 UpdatePanel 中的一個UpdatePanel)發起的,觸發此子 UpdatePanel 的觸發器将顯示子UpdatePanel 以及父UpdatePanel 的UpdateProgress模闆。但如果觸發器是UpdatePanel 的一個直接子UpdatePanel,那麼隻顯示與父UpdatePanel 相關聯的UpdateProgress模闆。

小結

Microsoft ASP.NET AJAX 擴充屬于尖端産品,旨在協助以使 web 内容更易于通路,并為您的 web 應用程式提供更豐富的使用者體驗。作為ASP.NET AJAX Extensions 的一部分,局部頁面呈現控件,包括ScriptManager、UpdatePanel 和UpdateProgress 控件,都是工具箱中最明顯的一些元件。

ScriptManager 元件內建了 Extensions 的用戶端 JavaScript 提供功能,并啟用了多種伺服器端和用戶端元件,将開發成本減到最低。

UpdatePanel 控件是明顯的“魔法箱”:UpdatePanel 中的标記可以有伺服器端的Codebehind且不觸發頁面重新整理。UpdatePanel 控件可以嵌套,也可與其他UpdatePanel 中的控件相關聯。預設情況下,UpdatePanel 對所有其子代控件調用的回傳都進行處理,但您也可聲明或通過編碼對其進行調整。

使用 UpdatePanel 控件時,開發者應了解可能産生的性能影響。可能的替代方案包括web 服務和頁面方法,但也應考慮到應用程式的設計問題。

UpdateProgress控件可以使使用者知道操作仍在進行中,以及在頁面未對使用者輸入進行任何響應時,幕後的請求正在執行。它還提供了放棄局部解析結果的功能。

通過降低伺服器的運作對使用者的可見性以及保持工作流的連續性,這些工具共同建立豐富無縫的使用者體驗。

快樂程式設計!

<script type=”text/javascript”> <!-- Sys.WebForms.PageRequestManager.getInstance().add_EndRequest(Request_End); function Request_End(sender, args) { if (args.get_error() != undefined) { var errorMessage = “”; if (args.get_response().get_statusCode() == “200”) { errorMessage = args.get_error().message; } else { // the server wasn’t the problem... errorMessage = “An unknown error occurred...”; } // do something with the errorMessage here. // now make sure the system knows we handled the error. args.set_errorHandled(true); } } // --></script> <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %><%@ Register Assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI" TagPrefix="asp" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html > <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager EnablePartialRendering="true" ID="ScriptManager1" runat="server"></asp:ScriptManager> <div> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:Label ID="Label1" runat="server" Text="This is a label!"></asp:Label> <asp:Button ID="Button1" runat="server" Text="Click Me" OnClick="Button1_Click" /> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body></html> public partial class _Default : System.Web.UI.Page{ protected void Button1_Click(object sender, EventArgs e) { Label1.Text = "You clicked the button!"; }} <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html > <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Label ID="Label1" runat="server" Text="This is a label!"> </asp:Label> <asp:Button ID="Button1" runat="server" Text="Click Me" OnClick="Button1_Click" /> </div> </form> </body></html>

繼續閱讀