欢迎您访问我爱IT技术网,今天小编为你分享的编程技术是:【asp.net客户端回调功能的实现机制】,下面是详细的分享!
asp.net客户端回调功能的实现机制
实现的过程基本上就是:让要实现客户端回调功能的页面或者空间实现System.Web.UI.ICallbackEventHandler的接口,即2个方法:void RaiseCallbackEvent(string eventArgument),这个是当客户端触发服务器端事件的委托方法,string GetCallbackResult();这个是返回客户端需要的值,只能是string 型的,当然你也可以返回一个Json串。
然后在pageload的时候注册脚本到客户端:在这里注册一个CallServer方法来调用服务器端方法,ReceiveServerData来捕获服务器返回的结果。当然你也可以使用一个方法来捕获服务器端的错误,详见Page.ClientScript.RegisterClientScriptBlock这个方法的MSDN解释。
这样就能实现客户端的回调服务器端事件,并返回值。
生成好页面后,查看源代码:
首先是多了一个js资源文件,多了一行这样的代码:
在body快结束的时候还有一段这样的代码:
WebForm_InitCallback();好,这些应该就是asp.net为了实现客户端回调所作的补充工作了吧,咱们来研究吧。
首先看js资源文件(20多K,汗一个...)。先在资源文件里面找到这个方法,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}这个方法就是把表单里面所有的值全部装载到一个键值对里面去。 |
| 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在初始化客户端回调功能的时候,其实就是将表单里面的所有键值对全部装载到一个全局的键值对里面去了。
然后,咱们来看看unction CallServer(arg, context){ WebForm_DoCallback('__Page',arg,ReceiveServerData,context,null,false);}所作的工作。
在示例中,点击按钮,就触发了CallServer方法,
| function LookUpStock() { var lb=document.getElementById("ListBox1"); var product=lb.options[lb.selectedIndex].text; CallServer(product, ""); } |
在资源文件中找到WebForm_DoCallback方法,由于方法太长太大,只有分段解析:
| 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) { } } |
这段代码是将一些参数附加上去到postData变量上。并创建xmlRequest对象。不过这个创建异步对象方法似乎有点不妥,他是先看是否是非IE的浏览器,然后被cacth住了才创建ActiveX对象,也就是说在IE大行其道的时候不得不多次catch,为什么不把创建ActiveX对象放在前面节省资源呢?不管这么多,接下来看:
| 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; } |
这几段语句最重要的是将异步回调方法赋值为:WebForm_CallbackComplete。
不过俺们还忽略了一些细节,让我们从头再来。上面有一段代码
| if (setRequestHeaderMethodExists) 也就是说在setRequestHeaderMethodExists这个变量不为null的时候才能够发送异步对象,那么这个变量是怎么定义的呢?? var setRequestHeaderMethodExists=true; try { setRequestHeaderMethodExists=(xmlRequest && xmlRequest.setRequestHeader); } |
也就是说只有当正确的创建了xmlRequest对象后才能够使用ajax,那么如果不能够正确创建ajax对象怎么办呢?接着看代码!
| 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=http://www.chinaz.com/program/2008/0528/callBackFrameUrl; } } catch(e) {} document.body.appendChild(xmlRequestFrame); } |
接下来原来是创建一个iframe!呵呵,原来是保证所有的浏览器都能使用ajax才出的这招。
再下来应该就是给这个iframe里面加载一些变量了,并且提交这个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(' '); |
原来在最开始初始化客户端回调的方法就是为了在不能够正确创建ajax对象的时候,将表单的值全部初始化到另外的iframe里面去的。
好了,整个asp.net客户端回调的请求发送部分分析完了,看来回调部分要下次了。
如果有分析不对的地方还请大侠指正!
以上所分享的是关于asp.net客户端回调功能的实现机制,下面是编辑为你推荐的有价值的用户互动:
相关问题:asp.net运行机制和原理是什么?
答:当一个HTTP请求到服务器并被IIS接收到之后,IIS首先通过客户端请求的页面类型为其加载相应的.dll文件,然后在处理过程中将这条请求发送给能够处理这个请求的模块。在ASP.NET 3.5中,这个模块叫做HttpHandler(HTTP处理程序组件),之所以.aspx文... >>详细
相关问题:在ASP.NET中什么是页面回发 什么是回调 热心人指点...
答:页面回发将重新创建页面及其控件,并在服务器上运行页面代码,最后将完整的新版本页面发送到浏览器端重新呈现。在客户端回调中,使用浏览器端脚本函数(一般为JavaScript函数)向服务器端的当前页面类对象发送请求。当前页面类对象运行其正常生... >>详细
相关问题:ASP.NET的页面机制
答:IIS处理页面的运行机制: IIS自身是不能处理像ASPX扩展名这样的页面,只能直接请求像HTML这样的静态文件,之所以能处理ASPX这样扩展名的页面,是因为IIS有一个ISAPI(Internet Server Application Programe Interface,互联网服务器应用程序接口)... >>详细
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
