之前遇到一個要求需要能夠取消一個正在進行中的Web Service這也是我第一次遇到這個功能不過不難我想既然ASPNET AJAX的客戶端與服務器端通信完全通過Microsoft AJAX Library的異步通信層進行那麼我們只要得到正在請求Web Service的SysNetWebRequest對象調用其abort方法就可以了但是究竟應該如何得到這個對象呢?於是我粗略地閱讀了一下代碼
首先假設有如下的Web Service方法定義(DemoServiceasmx)
[ScriptService]
public class DemoService : SystemWebServicesWebService
{
[WebMethod]
public string DemoMethod()
{
return Hello World;
}
}
訪問DemoServiceasmx/jsdebug(或者將其使用ScriptManager引用到頁面中之後)就能夠得到如下的代理(片斷經過排版)類
var DemoService = function()
{
DemoServiceinitializeBase(this);
this_timeout = ;
this_userContext = null;
this_succeeded = null;
this_failed = null;
}
DemoServiceprototype =
{
DemoMethod:function(succeededCallback failedCallback userContext)
{
return this_invoke(
DemoServiceget_path()
DemoMethod
false
{}
succeededCallback
failedCallback
userContext);
}
}
DemoServiceregisterClass(DemoServiceSysNetWebServiceProxy);
顯然這個代理類繼承了SysNetWebServiceProxy類於是我就把目光轉向了其中的_invoke方法
function Sys$Net$WebServiceProxy$_invoke(
servicePath methodName useGet params onSuccess onFailure userContext) {
// validation omitted
return SysNetWebServiceProxyinvoke(
servicePath
methodName
useGet
params
onSuccess
onFailure
userContext
thisget_timeout());
}
這下又將操作委托給了SysNetWebServiceProxyinvoke靜態方法繼續看代碼
SysNetWebServiceProxyinvoke = function Sys$Net$WebServiceProxy$invoke(
servicePath methodName useGet params onSuccess onFailure userContext timeout) {
// validation omitted
// Create a web request to make the method call
var request = new SysNetWebRequest();
// preparing request omitted
requestinvoke();
function onComplete(response eventArgs) {
// method body omitted
}
return request;
}
嗨這不就是我所需要的SysNetWebRequest對象嗎?原來想要得到這個對象那麼簡單於是我就寫下了下面的代碼
var request = DemoServiceDemoMethod(onComplete);
然後在必要時
requestabort();
執行出現了錯誤request為undefined為什麼DemoMethod方法調用沒有返回request對象?跟蹤了代碼之後不大不小地暈了一下原來問題出在這裡
DemoService_staticInstance = new DemoService();
DemoServiceDemoMethod = function(onSuccessonFaileduserContext)
{
DemoService_staticInstanceDemoMethod(onSuccessonFaileduserContext);
}
雖然早就知道Web Service代理會在類上創建一個Singleton對象並且創建靜態方法再委托給那個實例上的相應方法卻一直沒有意識到這個細節在上面的靜態方法中居然是直接調用了DemoMethod方法卻沒有將結果返回出來真讓我哭笑不得了一下
不過問題時非常容易解決的只要使用如下的方式在客戶端調用WebService方法就可以了
var request = DemoService_staticInstanceDemoMethod(onComplete);
不過這個做法似乎……有些奇怪?那麼您也可以這樣
var demoService = new DemoService();
var request = demoServiceDemoMethod(onComplete);
在這裡重新創建一個demoService對象似乎有些多余不過在某些時候也是非常有用的做法例如您需要將操作分為兩類一類的超時時間為秒而另一類為秒因此您就可以創建兩個代理對象分別設置不同的超時時間因為超時時間我們只能在Service的級別上設置而不能在調用方法時指定
From:http://tw.wingwit.com/Article/program/net/201311/11513.html