浅析ASP.NET AJAX

开发 后端
本文介绍ASP.NET AJAX提供的类已经足够大多数应用的需求,但是在某些特殊情况,可能需要做一些改变。

ASP.NET AJAX的许多功能会要求异步地访问服务器端,例如访问Web Services,Authentication/Profile Services(事实上和访问Web Services是相同的机制)和Partial Rendering。在ASP.NET AJAX中,所有的这些访问都是通过一个网络访问的基础结构来完成的,无一例外。

一般来说,ASP.NET AJAX提供的类已经足够大多数应用的需求,但是在某些特殊情况,可能需要做一些改变。因此,Network Communication Layer提供了一定程度上的扩展能力——通过提供自定义的WebRequestExecutor子类来替换默认设置:XMLHttpExecutor。这种改变能够应用于一个单独的WebRequest,也可以对全局进行一个设置。这个我们就能对于客户端的行为做一些简单的修改和补充。这样可以说是 Network Communication Layer唯一的“官方”扩展点,其实能力有限。至于使用一些灵活的办法从JavaScript语言特性能上进行的修改,在这里就忽略不计了。

这样我们就能对于客户端的行为做一些简单的修改和补充。那么如果对其进行大量的修改会怎么样?如果这种修改的确能够满足您的需要,当然可以。可是这样的话,Partial Rendering就很可能无法实现了。Partial Rendering的作法是在客户端和服务器端产生一个严谨的协议,用来传递和处理大量的数据。如果有任何改变被加诸于这些数据上,协议就被破坏了,这个可以说是ASP.NET AJAX的最重要的功能之一的控件也就失效了。

接下来,我们详细了解一下这整个流程的每个步骤。

一、创建Sys.Net.WebRequest

这是发起一个服务器请求的***步。首先建立一个Sys.Net.WebRequest对象,然后通过addHeader,set_url等方法设置这个请求的各个信息,然后调用add_complete方法来注册complete事件。请注意,这和CTP版本的Sys.Net.WebRequest不同。在CTP版本的Sys.Net.WebRequest中,存在着三个事件:complete,timeout和aborted,用户可以有选择地注册这些事件。在RTM的Sys.Net.WebRequest中,三个事件被合成了一个complete事件。不管这个Request的结果如何,都会在这个触发这个事件,用户需要在响应这个事件的方法里自行根据得到的Response的信息来分辨这个请求的状况。具体的判断方式稍后再进行说明。在创建完 WebRequest对象后,将调用它的invoke方法执行这个请求。一个WebRequest对象只能被 invoke一次。

二、将WebRequest对象交给WebRequestManager执行

在WebRequest对象的invoke方法被调用以后,它会调用 “Sys.Net.WebRequestManager.executeRequest(this)”将自身交给全局的 WebRequestManager执行。这里的WebRequestManager其实是Sys.Net._WebRequestManager类的实例。在初始化环境的时候,就会将这个类实例化一个对象,赋值到Sys.Net.WebRequestManager变量中,以一个Singleton的形象供别的方法调用。它会在处理Request的过程中在特定的时刻触发一些事件,用户可以依靠响应这些事件来改变Request的行为,例如阻止特定的 Request,或者改变Request的一些属性等等。

乍看下来,RTM版本中的WebRequestManager和CTP中的 WebRequestManager没有很大的区别嘛(引入了几个事件除外)。事实上,个人认为在这个方面Atlas打了自己一个耳光。在CTP版本的 WebRequestManager中,对于管理WebRequest有一套比较复杂的方法,其理由是能够更好地利用好浏览器的资源,以提高 WebRequest的效率。这就是Atlas对外一直声称的“Client Request Stack”,这一点被当作Atlas的重要特点来看待。不过这一点在RTM版本中被取消了,新的WebRequestManager在处理一个 WebRequest对象的时候仅仅是触发事件,然后简单地使用Executor来调用这个WebRequest对象。

下面列举了调用了executeRequest方法后的关键逻辑:
1. 检查WebRequest是否指定了WebRequestExecutor(这可以在构造WebRequest的时候指定)。
2. 如果WebRequest没有指定WebRequestExecutor,则使用set_executor方法分配默认的WebRequestExecutor
3. 构造Sys.Net.NetworkRequestEventArgs参数对象,触发WebRequestManager的invokingRequest事件。
4. 如果Sys.Net.NetworkRequestEventArgs对象的cancel属性为true,取消执行Request。
5. 调用executor对象的executeRequest方法,以执行Request。

三、WebRequestExecutor执行Request

在这里,以ASP.NET AJAX的默认WebRequestExecutor类:XMLHttpExecutor为例进行说明。在XMLHttpExecutor的 executeRequest方法被调用后,XMLHttpExecutor会构造一个XMLHttpRequest对象,并根据WebRequest的各项属性设定XMLHttpRequest的对象,并指定XMLHttpRequest对象的onreadystatechange为自身的私有方法 _onReadyStateChange。调用了executeRequest方法后的关键逻辑如下:
1. 构造XMLHttpRequest对象,并根据WebRequest对象的属性设定它的各项属性。
2. 使用window.setTimeout用于监听超时发生。
3. 调用XMLHttpRequest的send方法。

在timeout的响应方法中调用XMLHttpRequest的abort方法,并调用WebRequest的complete方法。在 _onReadyStateChange方法中清除监听timeout的Timer,并调用complete方法。当然,这只是个简单的描述,事实上还需要对Executor的属性进行设定。我们将在下篇文章中将对此进行详细讨论。在complete方法被调用后关键逻辑如下:
1. 触发WebRequestManager的completedRequest事件。
2. 触发WebRequest的complete事件。

四、用户响应WebRequest的complete事件

在响应WebRequest的complete事件时,需要对于所获得的结果进行判断,以确定这个Request的结果到底如何,是成功了,还是出错了,亦或是过期了?需要注意的是,我们虽然监听的是WebRequest对象的事件,但是回调函数的***个参数是WebRequestExecutor对象!executor对象在这里事实上应该被看作是一个response。我们就来简单看一下应该如何根据executor对象的属性来判断 Request的结果吧。为了对于这部分逻辑有简单而清晰的描述,我就使用代码片断来说明吧。代码框架如下:

  1. functiononComplete(response,eventArgs){  
  2. if(response.get_aborted()){  
  3. //Abort  
  4. }  
  5. elseif(response.get_responseAvailable()){  
  6. varstatusCode=response.get_statusCode();  
  7. if(((statusCode<200)||(statusCode>=300))){  
  8. //Error  
  9. }  
  10. else{  
  11. //Success  
  12. }  
  13. }  
  14. else{  
  15. if(response.get_timedOut()){  
  16. //Timeout  
  17. }  
  18. else{  
  19. //Error  
  20. }  
  21. }  

这就是判断一个Request结果的逻辑框架了,非常清晰。阅读过ASP.NET AJAX客户端代码的朋友们可以发现,在RTM版本中这段逻辑不只一次出现过。我们如果需要直接使用WebRequest对象时,也应该使用这个逻辑进行判断。

到这里,我们应该已经搞清楚了从一个WebRequest对象被构造出来以后,是如何通过WebRequestManager和 WebRequestExecutor而执行的,之间会触发哪些事件,而***又是如何通过Response(WebRequestExecutor)对象来获得Request的结果。在下一篇文章中,我们将通过分析WebRequestExecutor、XMLHttpExecutor以及相关类的实现,来了解应该如何自定义和使用一个WebRequestExecutor。

【编辑推荐】

  1. ASP.NET MVC Web应用程序工程
  2. IIS6的ASP.NET ISAPI请求处理过程
  3. ASP.NET控件的七种用户管理相关控件
  4. 对ASP.Net进行RSA加密
  5. ASP.NET得到数据库字符串的方法
责任编辑:佚名 来源: IT168
相关推荐

2009-07-28 15:28:35

ASP.NET AJA

2009-07-28 16:21:03

Asp.net AjaAutoComplet

2009-07-28 16:08:43

ASP.NET AJA

2009-07-22 16:05:34

ASP.NET AJA

2009-08-05 15:50:13

ASP.NET优点

2009-07-31 12:43:59

ASP.NET MVC

2009-07-22 16:11:43

ASP.NET AJA

2009-07-22 16:25:41

ASP.NET AJA

2009-07-22 16:17:39

ASP.NET AJA

2009-08-05 18:36:12

ASP.NET Che

2009-08-10 13:32:15

ASP.NET TimASP.NET组件设计

2009-07-29 13:50:26

UpdatePanelASP.NET

2009-07-20 10:16:13

配置ASP.NET A

2009-08-04 17:00:09

ASP.NET禁用Vi

2009-08-05 14:46:17

ASP.NET url

2009-07-20 16:23:01

ASP.NET授权模块

2009-07-28 13:35:18

2009-07-23 14:31:20

ASP.NET MVC

2009-07-27 10:18:12

TypeResolveASP.NET

2009-07-28 15:53:43

ASP.NET Web
点赞
收藏

51CTO技术栈公众号