淺談ASP.NET的Postback 實(shí)例代碼第2/2頁(yè)
上面的HTMLBody部分大體包括3個(gè)部分:
1. 定義了3個(gè)hidden field:
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTA0NDQ2OTE5OWRk281L4eAk7iZT10hzg+BeOyoUWBQ=" />
從他們的命名可以看出他們分別代表的意思:__EVENTTARGET代表觸發(fā)Event的Control的Unique name;__EVENTARGUMENT代表為Event Handler定義的額外的參數(shù);__VIEWSTATE:代表的是Viewstate。
2. 一段script:
<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>
定義了一個(gè)__doPostBack function完成Postback的操作,該function只有區(qū)區(qū)3行代碼,前兩行通過(guò)參數(shù)對(duì)上面定義的兩個(gè)hidden field賦值,然后向Server端提交表單。
3. 一段HTML對(duì)應(yīng)通過(guò)ASP.NET定義的Web Control。
<div>
<span id="LabelMessage" style="color:Red;"></span>
</div>
<div>
<input type="submit" name="Button1" value="Button1" id="Button1" />
<input type="button" name="Button2" value="Button2" onclick="javascript:__doPostBack('Button2','')" id="Button2" />
<input type="button" name="Button3" value="Button3" onclick="javascript:__doPostBack('Button3','')" id="Button3" />
div>
我們定義的3個(gè)Button被轉(zhuǎn)化成3個(gè)能向Server端提交表單的<input > Tag, 但是他們提交表的方式卻不一樣,第一個(gè)以<input type="submit">的方式提交,后面兩個(gè)通過(guò)調(diào)用javascript的方式提交表單(<input type="button">)。對(duì)于一個(gè)System.Web.UI.WebControls.Button,默認(rèn)采用第一種提交方式,但是我們通過(guò)設(shè)置UseSubmitBehavior屬性(這個(gè)屬性時(shí)ASP.NET 2.0新加的,1x沒(méi)有相應(yīng)的設(shè)置),改變其表單提交的行為。
當(dāng)用戶Click Button2的時(shí)候,調(diào)用__doPostBack,并傳入兩個(gè)參數(shù):一個(gè)代表出發(fā)Event的對(duì)象的Unique name,也就是Button2的名稱,另一個(gè)描述Event的額外信息的參數(shù),這里不需要,所以這里是空字符串。在__doPostBack中把這兩個(gè)參數(shù)賦值給兩個(gè)Hidden Field:__EVENTTARGET,__EVENTARGUMENT。然后向Server端提交表單,完成Postback。
然后我們來(lái)看看Server如何處理這個(gè)Postback,關(guān)于Web Page的生命周期在這里就不詳細(xì)介紹了。Server端通過(guò)__EVENTTARGET這個(gè)hidden field的值找到對(duì)應(yīng)的Server端的Control,通過(guò)Reflection確定該Control是否實(shí)現(xiàn)了System.Web.UI.IPostBackEventHandler Interface。如果該Control確實(shí)實(shí)現(xiàn)了該Interface,那么調(diào)用Page的RaisePostBackEvent方法,這是一個(gè)Virtual的方法,可以被Override。我們來(lái)看該方法的定義。
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void RaisePostBackEvent(IPostBackEventHandler sourceControl, string eventArgument)
{
sourceControl.RaisePostBackEvent(eventArgument);
}
我們可以看到該方法直接調(diào)用該sourceControl的RaisePostBackEvent,并傳入一個(gè)eventArgument參數(shù),在這個(gè)例子中sourceControl就是__EVENTTARGET對(duì)應(yīng)的Web Control:Button2,eventArgument就是__EVENTTARGET對(duì)應(yīng)的值:一個(gè)空字符串。Button2的類型是System.Web.UI.WebControls.Button。我們來(lái)看看System.Web.UI.WebControls.Button中的RaisePostBackEvent方法是如何定義的:
protected virtual void RaisePostBackEvent(string eventArgument)
{
base.ValidateEvent(this.UniqueID, eventArgument);
if (this.CausesValidation)
{
this.Page.Validate(this.ValidationGroup);
}
this.OnClick(EventArgs.Empty);
this.OnCommand(new CommandEventArgs(this.CommandName, this.CommandArgument));
}
這個(gè)方法也很簡(jiǎn)單,先進(jìn)行Validation,然后先后出發(fā)兩個(gè)Event:OnClick 和OnCommand,隨后調(diào)用對(duì)應(yīng)的Event handler,這和我們的輸出結(jié)果是吻合的。
這基本上就是整個(gè)Postback的整個(gè)程序執(zhí)行的過(guò)程,現(xiàn)在我們對(duì)我們的Page作一些小的有趣的改動(dòng),來(lái)驗(yàn)證一下:
Client端和Server端進(jìn)行交互的途徑就是提交表單(Form Submitting),而我們現(xiàn)在有兩種方式來(lái)提交表單:通過(guò)<input type="submit">控件;通過(guò)調(diào)用javascript:__doPostBack?;谶@一點(diǎn)我們?cè)贖tml中加了下面一段javascript:
<script type="text/javascript">
function postback()
{
__doPostBack('Button1','');
}
document.getElementById("Button2").onclick = postback;
document.getElementById("Button3").onclick = postback;
</script>
我們override Button2和Button3的onclick event,把'Button1作為參數(shù)傳入__doPostBack方法,可以想象,現(xiàn)在無(wú)論Click那個(gè)Button,程序都將認(rèn)為之Click Button1。有興趣的可以親自試試,無(wú)論Click那個(gè)Button,顯示的效果都將是下面的樣子:

接下來(lái)我們?nèi)∠厦娴母膭?dòng),在Server對(duì)Code作另一方面的嘗試。我們前面說(shuō)過(guò),Server接受到Client的Postback,對(duì)于事件的Web Control(或者Html Server Control),如果實(shí)現(xiàn)了System.Web.UI.IPostBackEventHandler接口,會(huì)調(diào)用Page的virtual方法:RaisePostbackEvent,我們現(xiàn)在來(lái)Override這個(gè)方法:
protected override void RaisePostBackEvent(IPostBackEventHandler sourceControl, string eventArgument)
{
sourceControl = this.Button1;
base.RaisePostBackEvent(sourceControl, eventArgument);
}
在上面的Code中,我們把sourceControl設(shè)為Button1,這樣無(wú)論在client端Click的那個(gè)Button,現(xiàn)在都將認(rèn)為是對(duì)Button的Click。運(yùn)行的結(jié)果和上面一樣。
通過(guò)上面的介紹,我們知道了Page的RaisePostBackEvent會(huì)調(diào)用Source Control的RaisePostBackEvent方法,這個(gè)方法是定義在IPostBackEventHandler接口中,很多Control都實(shí)現(xiàn)了這個(gè)方法,對(duì)于Button來(lái)說(shuō),這個(gè)方法是Virtual的,它可以被你Override,如果感興趣的話,可以自己寫(xiě)一個(gè)Custom Button,并Override該方法,看看執(zhí)行的情況,相信會(huì)使加深你對(duì)Postback的理解。
相關(guān)文章
.NET/ASP.NET Routing路由(深入解析路由系統(tǒng)架構(gòu)原理)
這篇文章主要介紹了.NET/ASP.NET Routing路由(深入解析路由系統(tǒng)架構(gòu)原理),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07ASP.NET Core開(kāi)發(fā)教程之Logging利用NLog寫(xiě)日志文件
一直很喜歡 NLog 的簡(jiǎn)潔和擴(kuò)展性,所以下面這篇文章主要給大家介紹了關(guān)于ASP.NET Core開(kāi)發(fā)教程之Logging利用NLog寫(xiě)日志文件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-07-07.NET?6開(kāi)發(fā)TodoList應(yīng)用之使用MediatR實(shí)現(xiàn)POST請(qǐng)求
對(duì)于稍微正式的項(xiàng)目,.NET工程上習(xí)慣的實(shí)現(xiàn)是通過(guò)使用比較成熟的類庫(kù)框架,有效地對(duì)業(yè)務(wù)邏輯進(jìn)行分類管理、消除冗余代碼,以達(dá)到業(yè)務(wù)邏輯職責(zé)清晰簡(jiǎn)潔的目的。在這個(gè)階段我們經(jīng)常使用的兩個(gè)類庫(kù)分別是AutoMapper和MediatR。本文將為大家介紹MediatR如何實(shí)現(xiàn)POST請(qǐng)求2021-12-12如何使用簽名保證ASP.NET MVC OR WEBAPI的接口安全
這篇文章主要介紹了如何使用簽名保證ASP.NET MVC OR WEBAPI的接口安全,幫助大家更好的理解和學(xué)習(xí)使用.net技術(shù),感興趣的朋友可以了解下2021-04-04.NET?Core利用BsonDocumentProjectionDefinition和Lookup進(jìn)行?join?
這篇文章主要介紹了.NET?Core利用BsonDocumentProjectionDefinition和Lookup進(jìn)行join關(guān)聯(lián)查詢,這里主要介紹一下查詢角色的所有用戶的例子,文章結(jié)合實(shí)例代碼給大家詳細(xì)講解,需要的朋友可以參考下2022-10-10Silverlight4 多語(yǔ)言實(shí)現(xiàn)的方法
這篇文章介紹了Silverlight4 多語(yǔ)言實(shí)現(xiàn)的方法,有需要的朋友可以參考一下2013-10-10解決ASP.NET Core Mvc文件上傳限制問(wèn)題實(shí)例
本篇文章主要介紹了解決ASP.NET Core Mvc文件上傳限制問(wèn)題,具有一定的參考價(jià)值,有需要的可以了解一下。2016-11-11C# 接口的隱式與顯示實(shí)現(xiàn)及適應(yīng)場(chǎng)景
以前在用到接口時(shí),從來(lái)沒(méi)注意到接口分為隱式實(shí)現(xiàn)與顯示實(shí)現(xiàn)。昨天在瀏覽博客時(shí)看到相關(guān)內(nèi)容,現(xiàn)在根據(jù)自己的理解記錄一下,方便日后碰到的時(shí)候溫習(xí)溫習(xí),需要的朋友可以了解下2012-12-12詳解在Azure上部署Asp.NET Core Web App
這篇文章主要介紹了詳解在Azure上部署Asp.NET Core Web App,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12.net采用ajax實(shí)現(xiàn)郵箱注冊(cè)和地區(qū)選擇實(shí)例
這篇文章主要介紹了.net采用ajax實(shí)現(xiàn)郵箱注冊(cè)和地區(qū)選擇的方法,以實(shí)例形式詳細(xì)講述了.net采用ajax的技巧,非常實(shí)用,需要的朋友可以參考下2014-10-10