当前位置:首页 > Asp.Net Ajax 学习笔记13 AJAX Library中异步通信层使用

Asp.Net Ajax 学习笔记13 AJAX Library中异步通信层使用

点击次数:887  更新日期:2010-12-29
\n

1、Microsoft Ajax Library的客户端架构


\n

MicrosoftAJAXLibrary的组成部分之一
负责ASP.NETAJAX框架中所有的客户端与服务器端的通信
其默认实现封装了XMLHttpRequest的功能 <script language=”javascript” type=”text/javascript”>
function getXMLHttpRequest()
{
if (window.XMLHttpRequest)
{
//适用于firefox浏览器创建异步通讯对象
return new window.XMLHttpRequest();
}
else
{
//适用于IE来创建异步通讯对象,两个是不同的版本
var progIDs = [ \'Msxml2.XMLHTTP\', \'Microsoft.XMLHTTP\' ];

for (var i = 0; i < progIDs.length; i++)
{
try
{
var xmlHttp = new ActiveXObject(progIDs[i]);
return xmlHttp;
}
catch (ex) { }
}

return null;
}
}

function sendRequest()
{
var xhr = getXMLHttpRequest();

xhr.open(“POST”, “Handlers/RandomNumber.ashx”);

//设置准备状态改变的回调函数
xhr.onreadystatechange = function()
{
//设置onReadyStateChange作为回调函数
//将异步通讯对象作为this的上下文
onReadyStateChange.apply(xhr);
}
xhr.send(null);
}

function onReadyStateChange()
{
//异步通讯对象的readyState的5种状态
//0 - (未初始化)还没有调用send()方法
//1 - (载入)已调用send()方法,正在发送请求
//2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
//3 - (交互)正在解析响应内容
//4 - (完成)响应内容解析完成,可以在客户端调用了
if (this.readyState == 4)
{
//Http响应状态,值很多,但是我们只需要知道200为正常返回
if (this.status == 200)
{
alert(this.responseText);
}
else
{
throw new Error();
}
}
}
</script>上例是不实用Asp.Net Ajax客户端架构,直接进行异步通讯的示例,在服务端是使用Response.Write来返回客户端数据


\n

2、使用Asp.Net Ajax异步通讯层


\n

Asp.Net Ajax异步通讯层主要有三个类WebRequest、WebRequestExecutor、WebRequestManager,这三个类都在Sys.Net命名空间下。


\n

WebRequest类:负责收集(存储)请求信息。


\n


\n

\n


\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
事件completed得到回复后触发,就是表明这个异步传输已经由服务器那边给出了回应,不管这个回应是错误的还是超时的
add_completed/remove_completed添加/移除completed事件的事件处理器
getResolvedUrl获得完整的URL
invoke执行(发送)请求
set_url(url)设置服务器响应页面/Handler的地址
get_headers()得到请求的头信息集合
set_body(data)设置发送到服务器的请求内容
set_httpVerb(verb)设置请求所用的Http方法(Post, Get, Put,)
set_timeout(time)设置超时时间

\n

get_executor()

得到发送请求的Executor对象
set_userContext设置附加于WebRequest的对象


\n

<script language=”javascript” type=”text/javascript”>
var webRequest = null;

function sendRequest(action)
{
var ff = [1, 2, 3, 4];
webRequest = new Sys.Net.WebRequest();
webRequest.set_url(“Handlers/Complex.ashx”);
webRequest.get_headers()["action"] = action;
webRequest.set_body(“data=” + encodeURIComponent(“Hello World!”));
webRequest.set_httpVerb(“POST”);
webRequest.set_timeout(3000);
webRequest.set_userContext(ff);
webRequest.add_completed(onCompleted);
webRequest.invoke();
}

function onCompleted(response, eventArgs)
{
//得到请求Request里面的设备上下文
alert(response.get_webRequest().get_userContext());
if (response.get_aborted())
{
alert(“Request aborted!”);
}
else if (response.get_responseAvailable())
{
var statusCode = response.get_statusCode();
if ((statusCode < 200) || (statusCode >= 300))
{
alert(“Error occurred!”);
}
else
{
alert(response.get_responseData());
// response.get_xml();
// response.get_object();
// response.getResponseHeader();
}
}
else if (response.get_timedOut())
{
alert(“Request timed out!”);
}
else
{
alert(“Error occurred!”);
}
}
</script>


\n

如上例是一个使用Microsoft Asp.Net Ajax架构来进行异步传输的例子,上例中有一个set_userContext(Object),这个方法是设置webRequest的用户上下文,设置以后,userContext的内容不会传输到服务端(据我观察),他将会把这个属性传到completed事件处理器中。在上例中使用到了WebRequestExecutor类,response就是WebRequestExecutor类,这个类的属性与方法如下
\n

\n


\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
abort()取消当前请求
executeRequest()执行请求
getAllResponseHeaders()获取回复内所有的头信息,返回值是一个集合
getResponseHeader(HeaderName)获取回复内指定的头信息
get_aborted()/set表示请求是否被取消
get_responseAvailable()表示是否得到了正确的结果
get_responseData()获得字符串形势的回复内容
get_started()表示请求是否已经开始
get_statusCode()表示回复状态的代码
get_statusText()表示回复状态的文字
get_timedOut()表示回复是否是超时状态
get_xml()获得xml形式的回复内容
get_webRequest()获得当前正在执行的WebRequest对象


\n

在上面两个类的方法和属性说明中,get_/set_开头的是属性,属性应该有响应的get/set方法,我只标明了一部分,但是有的属性肯定是只读属性,这里我没有明确标明,也没有尝试,在实际编程中,应该很容易知道哪个是只读属性。在发送请求的函数中可以使用webRequest.get_executor()来得到WebRequestExecutor类的实例,在completed事件处理函数中,可以通过webRequestExecutor.get_webRequest得到webRequest类的实例,有点循环引用的意思。


\n

3、WebRequestManager类的说明
\n

\n


\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
invokingRequest事件即将发出请求时触发,可用于取消某个请求
completedRequest事件请求结束时触发,它早于WebRequest对象的completed事件触发
defaultTimeout属性默认的超时时间
defaultExecutorType默认的发送请求的Executor类型
add/remove_invokingRequest(handler)添加/移除invokingRequest的事件处理器
add/remove_completedRequest(handler)添加/移除completedRequest的事件处理器


\n

<asp:ScriptManager ID=”ScriptManager1″ runat=”server” />

<asp:UpdatePanel ID=”UpdatePanel1″ runat=”server”>
<ContentTemplate>
<%= DateTime.Now %><br />
<asp:Button ID=”Button1″ runat=”server” Text=”Button” />
</ContentTemplate>
</asp:UpdatePanel>

<script language=”javascript” type=”text/javascript”>
Sys.Net.WebRequestManager.add_invokingRequest(function(sender, eventArgs)
{
debugger
if (confirm(“Cancel the partial rendering?”))
{
eventArgs.set_cancel(true);
}
});

Sys.Net.WebRequestManager.add_completedRequest(function()
{
alert(“Response received!”);
});
</script>记得UpdatePanel中有一个PageRequestManager类,这个类适用与页面级别的调用,WebRequestManager是对web请求适用,并且PageRequestManager的initializeRequest事件优先与invokingRequest事件,从名字上就可以区分出来一个是初始化事件,一个是调用请求的事件。上面这个例子有一个bug,取消请求之后要重新刷新页面才能正常的调用。这个bug我还没有找到好的方法解决。注意:在这个例子中WebRequestManager类是结合UpdatePanel使用的,能否在与WebRequest和WebRequestExecutor类结合使用,在后面的课程中有讲述

\n