ASP.NET AJAX 中在客户端用 WebRequest 调用 Web Service

熟悉 ASP.NET AJAX 的人都知道,在客户端调用 Web Service 最简便、最标准的方法就是使用 ScriptManager 为我们生成的 Web Service 代理。例如有以下 Web Service:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> [WebService(Namespace = " http://tempuri.org/ " )]
[WebServiceBinding(ConformsTo
= WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(
false )]
[System.Web.Script.Services.ScriptService]
public class WebService1:System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld( string name)
{
return " Hello " + name + " ! " ;
}
}

我们在客户端调用此服务时,通常只需两个步骤即可:

1.在页面中添加 ScriptManager 控件并增加对 Web Service 的引用。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> < asp:ScriptManagerID = " ScriptManager1 " runat = " server " >
< Services >
< asp:ServiceReferencePath = " Services/WebService1.asmx " />
</ Services >
</ asp:ScriptManager >

2.用 Web Service 客户端代理调用 Web Service。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> < scripttype = " text/javascript " >
WebService1.HelloWorld(
" Junchieh " ,onCompleted);

function onCompleted(result){
alert(result);
}
< / script>

非常简单就搞定了。但如果我们不使用 ScriptManager 为我们提供的 Web Service 代理,而是采用比较原始的方法——使用 WebRequest 对象来调用上面的那个 Web Service,我们又该如何做呢?

看到这里,某些读者肯定会有这种想法:“这不是没事找事吗?有现成的代理不用,而去用那么原始且简陋的 WebRequest ……”。话虽不错,但这正是我们今天在这里要讨论和研究的主题——ASP.NET AJAX 客户端调用 Web Service 的原理。而剖析这一原理最佳方法就是借助于 WebRequest 对象来“拜访”一下 Web Service。因此,本文的学术性要高于实用性。如果您和我一样,想要探究一下 ASP.NET AJAX 中客户端调用 Web Service 的工作原理,那么就请和我一起继续研究下去吧。

我们首先来研究一下刚才使用客户端 Web Service 代理调用 Web Service 时产生的请求和响应数据。要观察这些数据,我们可借助于著名的 HTTP 嗅探器——Fiddler (下载地址:http://www.fiddlertool.com/fiddler/version.asp)。在执行上述客户端代码后,我们在 Fiddler 中通过分析请求的数据发现,headers 中的 Content-Type 为“application/json; charset=utf-8”:

ASP.NET AJAX 中在客户端用 WebRequest 调用 Web Service

请求的 body 为“{"name":"Junchieh"}”:

ASP.NET AJAX 中在客户端用 WebRequest 调用 Web Service

响应的数据中,headers 的 Content-Type 同样也是“application/json; charset=utf-8”:

ASP.NET AJAX 中在客户端用 WebRequest 调用 Web Service

body 为“{"d":"Hello Junchieh!"}”:

ASP.NET AJAX 中在客户端用 WebRequest 调用 Web Service

由此我们可以得出结论:ASP.NET AJAX 中在客户端用 Web Service 代理调用 Web Service 时所产生的请求和响应的数据类型(Content-Type)均为“application/json; charset=utf-8”。也就是说,在请求和响应的过程中均使用了 JSON 数据格式。有了这些研究成果,我们使用 WebRequest 实现相同的功能就容易的多了。请看下列客户端代码:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> < scripttype = " text/javascript " >
var wr = new Sys.Net.WebRequest();
wr.set_body(
" {'name':'Junchieh'} " ); // 把要传给WebService方法的参数构造成JSON字符串
wr.get_headers()[ " Content-Length " ] = wr.get_body().length;
wr.get_headers()[
" Content-Type " ] = " application/json;charset=utf-8 " ; // 这是最关键的
wr.set_url( " Services/WebService1.asmx/HelloWorld " );
wr.add_completed(onCompleted);
wr.invoke();

function onCompleted(executor,eventArgs){
if (executor.get_responseAvailable()){
// 从WebService返回的数据是JSON格式的字符串,所以要对此字符串进行反序列化,将其转化为JavaScript对象
var result = Sys.Serialization.JavaScriptSerializer.deserialize(executor.get_responseData());
alert(result.d);
}
}
< / script>

以上代码的关键部分包括:

1.在 set_body 方法中传入JSON 形式字符串参数。

2.用get_headers 方法取到 HTTP 头后将其“Content-Type”设置为“application/json; charset=utf-8”。如果我们没有设置此属性,默认值将是“application/x-www-form-urlencoded; charset=utf-8”(您可以将这部分析代码注释掉,刷新页面后在 Fiddler中看一下)。

3.在取得返回的数据后,将数据反序列化成 JavaScript 对象。在上述代码中我们是通过 ASP.NET AJAX 的 JavaScriptSerializer.deserialize 方法实现的。

运行以上代码后,我们会看到下图所示的 alert 窗口:

ASP.NET AJAX 中在客户端用 WebRequest 调用 Web Service

至此,我们用 WebRequest 对象来“模拟”Web Service 客户端代理访问 WebService 取得了成功。从中我们又可以得出另一结论:ASP.NET AJAX 的 Web Service 客户端代理自动为我们完成了上面的三个关键部分的代码,让我们可以用一行 JavaScript 代码就可以完成对 Web Service 方法的调用。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> WebService1.HelloWorld( " Junchieh " ,onCompleted);

你可能感兴趣的:(Web,service)