傳統 ASP 時代,只有 <input type="submit"> 能提交表單。ASP.NET 引入 LinkButton、ImageButton、DropDownList 等控制項,它們外觀不像提交按鈕,卻能觸發 Postback。核心秘密在於客戶端腳本 __doPostBack 與兩個隱藏欄位 __EVENTTARGET、__EVENTARGUMENT。
<script type="text/javascript">
var theForm = document.forms['form1'];
if (!theForm) theForm = document.form1;
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
</script>
<a id="lnkBtn" href="javascript:__doPostBack('lnkBtn','')">Click Me</a>
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
點擊連結 → 呼叫 __doPostBack('lnkBtn', '') → 將控制項 ID 寫入隱藏欄位 → form.submit() → 伺服器端接收 POST 請求。
Page.Load 階段,ASP.NET 讀取 Request.Form["__EVENTTARGET"] 取得控制項 UniqueID,透過 Page.FindControl 定位控制項,並呼叫其 RaisePostBackEvent 引發對應事件(Click、SelectedIndexChanged 等)。
protected internal override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (Page != null && Enabled)
{
Page.RegisterPostBackScript(); // 註冊 __doPostBack 腳本
if (CausesValidation && Page.GetValidators(ValidationGroup).Count > 0
|| !string.IsNullOrEmpty(PostBackUrl))
{
Page.RegisterWebFormsScript(); // 註冊驗證腳本
}
}
}
RegisterPostBackScript:確保頁面有 __doPostBack 函數與隱藏欄位。IPostBackEventHandler 介面:控制項必須實作 RaisePostBackEvent(string eventArgument) 才能接收事件。href="javascript:__doPostBack('ctl00$lnkBtn','')"__doPostBack 將 'ctl00$lnkBtn' 寫入 __EVENTTARGETPage.LoadPostData → RaisePostBackEventctl00$lnkBtn 對應的 LinkButton 實例RaisePostBackEvent → 引發 Click 事件lnkBtn_Click 事件處理器執行| 方法 | 輸出位置 | 用途 |
|---|---|---|
| RegisterClientScriptBlock | <form> 開始標籤後 | 函式定義、變數初始化 |
| RegisterStartupScript | </form> 結束標籤前 | 頁面載入後立即執行(如 alert、初始化 UI) |
| RegisterOnSubmitStatement | form.onsubmit 事件 | 提交前驗證、攔截 |
ASP.NET 控制項「無縫」與伺服器互動,本質是 JavaScript 表單提交包裝。理解 __doPostBack、__EVENTTARGET、IPostBackEventHandler 三者關係,有助於除錯自訂控制項、AJAX 整合、與前端框架共存等進階場景。