asp.net客戶端回調(diào)功能的實(shí)現(xiàn)機(jī)制_.Net教程
推薦:ASP.Net用MD5和SHA1加密的幾種方法首先簡(jiǎn)單介紹一下MD5和SHA1: MD5的全稱是Message-Digest Algorithm 5(信息-摘要算法),在90年代初由Mit Laboratory for Computer Science和Rsa data security inc的Ronald l. rivest開(kāi)發(fā)出
實(shí)現(xiàn)的過(guò)程基本上就是:讓要實(shí)現(xiàn)客戶端回調(diào)功能的頁(yè)面或者空間實(shí)現(xiàn)System.Web.UI.ICallbackEventHandler的接口,即2個(gè)方法:void RaiseCallbackEvent(string eventArgument),這個(gè)是當(dāng)客戶端觸發(fā)服務(wù)器端事件的委托方法,string GetCallbackResult();這個(gè)是返回客戶端需要的值,只能是string 型的,當(dāng)然你也可以返回一個(gè)Json串。
然后在pageload的時(shí)候注冊(cè)腳本到客戶端:在這里注冊(cè)一個(gè)CallServer方法來(lái)調(diào)用服務(wù)器端方法,ReceiveServerData來(lái)捕獲服務(wù)器返回的結(jié)果。當(dāng)然你也可以使用一個(gè)方法來(lái)捕獲服務(wù)器端的錯(cuò)誤,詳見(jiàn)Page.ClientScript.RegisterClientScriptBlock這個(gè)方法的MSDN解釋。
這樣就能實(shí)現(xiàn)客戶端的回調(diào)服務(wù)器端事件,并返回值。
生成好頁(yè)面后,查看源代碼:
首先是多了一個(gè)js資源文件,多了一行這樣的代碼:
在body快結(jié)束的時(shí)候還有一段這樣的代碼:
WebForm_InitCallback();好,這些應(yīng)該就是asp.net為了實(shí)現(xiàn)客戶端回調(diào)所作的補(bǔ)充工作了吧,咱們來(lái)研究吧。
首先看js資源文件(20多K,汗一個(gè)...)。先在資源文件里面找到這個(gè)方法,WebForm_InitCallback();
方法如下:
| 1function WebForm_InitCallback() { 2 var count = theForm.elements.length; 3 var element; 4 for (var i = 0; i < count; i ) { 5 element = theForm.elements[i]; 6 var tagName = element.tagName.toLowerCase(); 7 if (tagName == "input") { 8 var type = element.type; 9 if ((type == "text" type == "hidden" type == "password" 10 ((type == "checkbox" type == "radio") & element.checked)) && 11 (element.id != "__EVENTVALIDATION")) { 12 WebForm_InitCallbackAddField(element.name, element.value); 13 } 14 } 15 else if (tagName == "select") { 16 var selectCount = element.options.length; 17 for (var j = 0; j < selectCount; j ) { 18 var selectChild = element.options[j]; 19 if (selectChild.selected == true) { 20 WebForm_InitCallbackAddField(element.name, element.value); 21 } 22 } 23 } 24 else if (tagName == "textarea") { 25 WebForm_InitCallbackAddField(element.name, element.value); 26 } 27 } 28}這個(gè)方法就是把表單里面所有的值全部裝載到一個(gè)鍵值對(duì)里面去。 |
| function WebForm_InitCallbackAddField(name, value) { var nameValue = new Object(); nameValue.name = name; nameValue.value = value; __theFormPostCollection[__theFormPostCollection.length] = nameValue; __theFormPostData = name "=" WebForm_EncodeCallback(value) "&"; } function WebForm_EncodeCallback(parameter) { if (encodeURIComponent) { return encodeURIComponent(parameter); } else { return escape(parameter); } } |
那么就是asp.net在初始化客戶端回調(diào)功能的時(shí)候,其實(shí)就是將表單里面的所有鍵值對(duì)全部裝載到一個(gè)全局的鍵值對(duì)里面去了。
然后,咱們來(lái)看看unction CallServer(arg, context){ WebForm_DoCallback('__Page',arg,ReceiveServerData,context,null,false);}所作的工作。
在示例中,點(diǎn)擊按鈕,就觸發(fā)了CallServer方法,
| function LookUpStock() { var lb = document.getElementById("ListBox1"); var product = lb.options[lb.selectedIndex].text; CallServer(product, ""); } |
在資源文件中找到WebForm_DoCallback方法,由于方法太長(zhǎng)太大,只有分段解析:
| unction WebForm_DoCallback(eventTarget, eventArgument, eventCallback, context, errorCallback, useAsync) { var postData = __theFormPostData "__CALLBACKID=" WebForm_EncodeCallback(eventTarget) "&__CALLBACKPARAM=" WebForm_EncodeCallback(eventArgument); if (theForm["__EVENTVALIDATION"]) { postData = "&__EVENTVALIDATION=" WebForm_EncodeCallback(theForm["__EVENTVALIDATION"].value); } var xmlRequest,e; try { xmlRequest = new XMLHttpRequest(); } catch(e) { try { xmlRequest = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) { } } |
這段代碼是將一些參數(shù)附加上去到postData變量上。并創(chuàng)建xmlRequest對(duì)象。不過(guò)這個(gè)創(chuàng)建異步對(duì)象方法似乎有點(diǎn)不妥,他是先看是否是非IE的瀏覽器,然后被cacth住了才創(chuàng)建ActiveX對(duì)象,也就是說(shuō)在IE大行其道的時(shí)候不得不多次catch,為什么不把創(chuàng)建ActiveX對(duì)象放在前面節(jié)省資源呢?不管這么多,接下來(lái)看:
| var setRequestHeaderMethodExists = true; try { setRequestHeaderMethodExists = (xmlRequest && xmlRequest.setRequestHeader); } catch(e) {} var callback = new Object(); callback.eventCallback = eventCallback; callback.context = context; callback.errorCallback = errorCallback; callback.async = useAsync; var callbackIndex = WebForm_FillFirstAvailableSlot(__pendingCallbacks, callback); if (!useAsync) { if (__synchronousCallBackIndex != -1) { __pendingCallbacks[__synchronousCallBackIndex] = null; } __synchronousCallBackIndex = callbackIndex; } if (setRequestHeaderMethodExists) { xmlRequest.onreadystatechange = WebForm_CallbackComplete; callback.xmlRequest = xmlRequest; xmlRequest.open("POST", theForm.action, true); xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlRequest.send(postData); return; } |
這幾段語(yǔ)句最重要的是將異步回調(diào)方法賦值為:WebForm_CallbackComplete。
不過(guò)俺們還忽略了一些細(xì)節(jié),讓我們從頭再來(lái)。上面有一段代碼
| if (setRequestHeaderMethodExists) 也就是說(shuō)在setRequestHeaderMethodExists這個(gè)變量不為null的時(shí)候才能夠發(fā)送異步對(duì)象,那么這個(gè)變量是怎么定義的呢?? var setRequestHeaderMethodExists = true; try { setRequestHeaderMethodExists = (xmlRequest && xmlRequest.setRequestHeader); } |
也就是說(shuō)只有當(dāng)正確的創(chuàng)建了xmlRequest對(duì)象后才能夠使用ajax,那么如果不能夠正確創(chuàng)建ajax對(duì)象怎么辦呢?接著看代碼!
| callback.xmlRequest = new Object(); var callbackFrameID = "__CALLBACKFRAME" callbackIndex; var xmlRequestFrame = document.frames[callbackFrameID]; if (!xmlRequestFrame) { xmlRequestFrame = document.createElement("IFRAME"); xmlRequestFrame.width = "1"; xmlRequestFrame.height = "1"; xmlRequestFrame.frameBorder = "0"; xmlRequestFrame.id = callbackFrameID; xmlRequestFrame.name = callbackFrameID; xmlRequestFrame.style.position = "absolute"; xmlRequestFrame.style.top = "-100px" xmlRequestFrame.style.left = "-100px"; try { if (callBackFrameUrl) { xmlRequestFrame.src = callBackFrameUrl; } } catch(e) {} document.body.appendChild(xmlRequestFrame); } |
接下來(lái)原來(lái)是創(chuàng)建一個(gè)iframe!呵呵,原來(lái)是保證所有的瀏覽器都能使用ajax才出的這招。
再下來(lái)應(yīng)該就是給這個(gè)iframe里面加載一些變量了,并且提交這個(gè)iframe了:
| var interval = window.setInterval(function() { xmlRequestFrame = document.frames[callbackFrameID]; if (xmlRequestFrame && xmlRequestFrame.document) { window.clearInterval(interval); xmlRequestFrame.document.write(""); xmlRequestFrame.document.close(); xmlRequestFrame.document.write(' '); |
原來(lái)在最開(kāi)始初始化客戶端回調(diào)的方法就是為了在不能夠正確創(chuàng)建ajax對(duì)象的時(shí)候,將表單的值全部初始化到另外的iframe里面去的。
好了,整個(gè)asp.net客戶端回調(diào)的請(qǐng)求發(fā)送部分分析完了,看來(lái)回調(diào)部分要下次了。
如果有分析不對(duì)的地方還請(qǐng)大俠指正!
分享:asp.net中生成縮略圖并添加版權(quán)//定義image類的對(duì)象 Drawing.Image image,newimage; //圖片路徑 protected string imagePath; //圖片類型 protected string imageType; //圖片名稱 protected string imageName; //提供一個(gè)
- asp.net如何得到GRIDVIEW中某行某列值的方法
- .net SMTP發(fā)送Email實(shí)例(可帶附件)
- js實(shí)現(xiàn)廣告漂浮效果的小例子
- asp.net Repeater 數(shù)據(jù)綁定的具體實(shí)現(xiàn)
- Asp.Net 無(wú)刷新文件上傳并顯示進(jìn)度條的實(shí)現(xiàn)方法及思路
- Asp.net獲取客戶端IP常見(jiàn)代碼存在的偽造IP問(wèn)題探討
- VS2010 水晶報(bào)表的使用方法
- ASP.NET中操作SQL數(shù)據(jù)庫(kù)(連接字符串的配置及獲取)
- asp.net頁(yè)面?zhèn)髦禍y(cè)試實(shí)例代碼
- DataGridView - DataGridViewCheckBoxCell的使用介紹
- asp.net中javascript的引用(直接引入和間接引入)
- 三層+存儲(chǔ)過(guò)程實(shí)現(xiàn)分頁(yè)示例代碼
.Net教程Rss訂閱編程教程搜索
.Net教程推薦
- 淺談ADO.NET Entity Framework存取數(shù)據(jù)庫(kù)中圖片
- 解析C# 如何獲取圖片長(zhǎng)寬
- 如何使用.NET正則表達(dá)式區(qū)分中英文
- 解析標(biāo)題太長(zhǎng)用省略號(hào)來(lái)代替簡(jiǎn)單辦法
- 淺析ASP.NET中前臺(tái)javascript與后臺(tái)代碼調(diào)用
- 幾種判斷asp.net中session過(guò)期方法的比較
- 解讀Web.config簡(jiǎn)要配置說(shuō)明
- ASP.NET2.0向其它網(wǎng)頁(yè)傳遞信息的方法
- 談.NET平臺(tái)編程語(yǔ)言的未來(lái)
- 淺談在.NET應(yīng)用程序中進(jìn)行Erlang風(fēng)格的并行編程
- 相關(guān)鏈接:
- 教程說(shuō)明:
.Net教程-asp.net客戶端回調(diào)功能的實(shí)現(xiàn)機(jī)制
。