作者: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
{
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
[WebMethod]
public string BadMethod(int delayTime, bool throwException)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// 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,
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
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;
![None.gif](/Images/OutliningIndicators/None.gif)
[WebService(Namespace
=
"
http://tempuri.org/
"
)]
[WebServiceBinding(ConformsTo
=
WsiProfiles.BasicProfile1_1)]
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
public
class
ComplexWebService : System.Web.Services.WebService
{
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
[WebMethod]
public string BadMethod(int delayTime, bool throwException)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (throwException)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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)
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
alert(result);
}
超时,指定服务器端延时3
秒,但超时时间设置成为仅1
秒:
function
btnTimeOut_onclick()
{
ComplexWebService.BadMethod(
3000,
false,
onBadMethodComplete,
onBadMethodTimeout,
onBadMethodError,
onBadMethodAborted,
"btnTimeOut_onclick",
1000
);
}
function
onBadMethodTimeout(request, userContext)
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
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)
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
var errorString = "Test '" + userContext + "' failed!";
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (result == null)
{
errorString += " Status code='" + response.get_statusCode() + "'";
}
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
else
{
errorString +=
" Message='" + result.get_message() +
"'\r\nstackTrace = " + 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();
}
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
function
onBadMethodAborted(request, userContext)
{
var errorString = "The call to '" + userContext + "' failed, request is aborted!";
alert(errorString);
}
截图如下,正常完成:
超时:
![controlws2.JPG](https://i-blog.csdnimg.cn/blog_migrate/ce8299a01ebdc0e934e740f61deb8e43.jpeg)
异常:
![controlws3.JPG](https://i-blog.csdnimg.cn/blog_migrate/1403812a41c1485e3bd3bd16b4aa9e5e.jpeg)
用户取消:
![controlws4.JPG](https://i-blog.csdnimg.cn/blog_migrate/7cc272f971937849147e5b12b6bbe98d.jpeg)
该示例程序可以在此下载:http://files.cnblogs.com/dflying/ControlTheWebService.zip
转载于:https://www.cnblogs.com/dflying/archive/2006/05/17/Atlas_and_Web_Service__Error_Timeout_and_User_Abort_Handling.html