資料源於網絡
熟悉 ASP.NET AJAX 的人都知道,在客戶端調用 Web Service 最簡便、最標準的方法就是使用 ScriptManager 爲我們生成的 Web Service 代理。例如有以下 Web Service:
[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 的引用。
<Services>
<asp:ServiceReference Path="Services/WebService1.asmx" />
</Services>
</asp:ScriptManager>
2.用 Web Service 客戶端代理調用 Web Service。
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”:
請求的 body 爲“{"name":"Junchieh"}”:
響應的數據中,headers 的 Content-Type 同樣也是“application/json; charset=utf-8”:
body 爲“{"d":"Hello Junchieh!"}”:
由此我們可以得出結論:ASP.NET AJAX 中在客戶端用 Web Service 代理調用 Web Service 時所產生的請求和響應的數據類型(Content-Type)均爲“application/json; charset=utf-8”。也就是說,在請求和響應的過程中均使用了 JSON 數據格式。有了這些研究成果,我們使用 WebRequest 實現相同的功能就容易的多了。請看下列客戶端代碼:
var wr = new Sys.Net.WebRequest();
wr.set_body("{'name':'Junchieh'}"); // 把要傳給 Web Service 方法的參數構造成 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()) {
// 從 Web Service 返回的數據是 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 窗口:
至此,我們用 WebRequest 對象來“模擬”Web Service 客戶端代理訪問 WebService 取得了成功。從中我們又可以得出另一結論:ASP.NET AJAX 的 Web Service 客戶端代理自動爲我們完成了上面的三個關鍵部分的代碼,讓我們可以用一行 JavaScript 代碼就可以完成對 Web Service 方法的調用。