作者:Dflying Chen( http://dflying.cnblogs.com/ )
在本系列的上一篇(在ASP.NET Atlas中呼叫Web Service-介紹及簡單應用)中,我們熟悉了Atlas中呼叫Web Service的最基礎方法,但是在實際開發中,僅發出請求並等待回傳結果是不夠的,我們大都需要考慮對錯誤逾時等的處理,也要允許使用者取消操作。幸運的是,Atlas對Web Service中的Web Method的封裝也充分考慮到了這些需求。
讓我們舉一個Web Method的例子來說明,例如,對於如下的Web Method:
public class ComplexWebService : System.Web.Services.WebService {
[WebMethod]
public string BadMethod(int delayTime, bool throwException)
{
// something something
}
}
Atlas產生的JavaScript mash up將會有以下的簽章: ComplexWebService.BadMethod(
delayTime,
throwException,
onMethodComplete,
onMethodTimeout,
onMethodError,
onMethodAborted,
userContext,
timeoutInterval,
priority,
useGetMethod,
);
注意到Web Method中的兩個參數按照順序作為了JavaScript方法的前兩個參數,接下來還有一些額外的參數:
onMethodComplete:指定當該方法順利完成並返回時被觸發的回調函數名,一般情況下您應該總是指定這個方法。
onMethodTimeout,:指定當此方法執行逾時時被觸發的函數名稱。
onMethodError:指定當方法在執行中遇到異常時被觸發的函數名稱。
onMethodAborted:制定當此方法執行期間被使用者取消時被觸發的函數名稱。
userContext:使用者上下文對象,在上述四個函數中都可以存取。
timeoutInterval:設定超時的時間限制,單位毫秒,預設值好像為90000。一般情況下不需要更改。
priority:設定此方法的執行優先權。此優先權將被用於批量AJAX操作(將在下一篇中提及)中。
useGetMethod:是否採用HTTP GET來傳送請求,預設為false。
上述這八個屬性的順序必須按照指定的來。但有時候我們只需要指定順序後面的某個參數,就得同時書寫前面的參數。為此,Atlas刻意為我們提供了另一種呼叫方法,將上述八個參數以dictionary的形式傳給該方法。例如當我們只需要onMethodComplete和timeoutInterval參數時,可以這樣寫:
ComplexWebService.BadMethod(
delayTime,
throwException,
{
onMethodComplete: completeHandler,
timeoutInterval: 10000
}
);
OK,讓我們透過一個實例來看看在一般情況下上述四種回呼函數(onMethodComplete,onMethodTimeout,onMethodError和onMethodAborted)中的常見處理。
首先讓我們完成開頭部分的Web Service方法:
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
[WebService(Namespace = " http://tempuri.org/ ")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class ComplexWebService : System.Web.Services.WebService {
[WebMethod]
public string BadMethod(int delayTime, bool throwException)
{
if (throwException)
{
throw new Exception("Sorry, I do not like to do this!");
}
System.Threading.Thread.Sleep(delayTime);
return "Done!";
}
}
可以看到方法有兩個參數:delayTime指定方法的延遲,throwException指定方法是否擲出例外。透過控制這兩個參數以及呼叫時的timeoutInterval參數,我們就可以模擬完成,超時以及異常的三種情況。
然後,在頁面中加入ScriptManager並加入這個Web Service的參考:
<atlas:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<atlas:ServiceReference Path="ComplexWebService.asmx" />
</Services>
</atlas:ScriptManager>
在ASPX頁面上新增四個按鈕,用來觸發下述四種情況: <div>
This is a BAD method, it can:<br />
<input id="btnWorkFine" type="button" value="work fine" onclick="return btnWorkFine_onclick()" />
<input id="btnTimeOut" type="button" value="timeout" onclick="return btnTimeOut_onclick()" />
<input id="btnThrowException" type="button" value="throw an exception" onclick="return btnThrowException_onclick()" />
<input id="btnCanceld" type="button" value="get canceled" onclick="return btnCanceld_onclick()" />
</div>
正常完成,我們指定伺服器端沒有延遲也沒有異常,並給出了一個合理的(10秒)的超時時間:
function btnWorkFine_onclick() {
ComplexWebService.BadMethod(
0,
false,
onBadMethodComplete,
onBadMethodTimeout,
onBadMethodError,
onBadMethodAborted,
"btnWorkFine_onclick",
10000
);
}
function onBadMethodComplete(result)
{
alert(result);
}
逾時,指定伺服器端延遲3秒,但逾時時間設定變成僅1秒:
function btnTimeOut_onclick() {
ComplexWebService.BadMethod(
3000,
false,
onBadMethodComplete,
onBadMethodTimeout,
onBadMethodError,
onBadMethodAborted,
"btnTimeOut_onclick",
1000
);
}
function onBadMethodTimeout(request, userContext)
{
var timeoutString = "The call to '" + userContext + "' failed due to time out!";
alert(timeoutString);
}
異常,制定伺服器端擲出異常。注意回呼函數中可以使用response參數得到詳細的錯誤訊息:
function btnThrowException_onclick() {
ComplexWebService.BadMethod(
0,
true,
onBadMethodComplete,
onBadMethodTimeout,
onBadMethodError,
onBadMethodAborted,
"btnThrowException_onclick",
10000
);
}
function onBadMethodError(result, response, userContext)
{
var errorString = "Test '" + userContext + "' failed!";
if (result == null) {
errorString += " Status code='" + response.get_statusCode() + "'";
}
else {
errorString +=
" Message='" + result.get_message() +
"'rnstackTrace = " + result.get_stackTrace();
}
alert(errorString);
}
使用者取消,與正常完成類似,不過在發出請求後立刻使用request.abort()取消了操作:
function btnCanceld_onclick() {
var request = ComplexWebService.BadMethod(
2000,
false,
onBadMethodComplete,
onBadMethodTimeout,
onBadMethodError,
onBadMethodAborted,
"btnCanceld_onclick",
10000
);
request.abort();
}
function onBadMethodAborted(request, userContext) {
var errorString = "The call to '" + userContext + "' failed, request is aborted!";
alert(errorString);
}
此範例程式可以在此下載: