Webservice异常处理之SoapException封装
Webservice客户端使用一个WebMethod时,如果WebMethod内部出现异常,不管异常是系统级异常或者自定义的异常,均会被包装为SoapException类型的异常,返回给客户端。 客户端再使用这种SoapException时,无法直接从异常类的属性中提取直接的业务异常信息。网上看到有两种做法,如下:
[1].做一个SoapException的Helper类,利用正则表达式的方式,从SoapException的属性做文法分析,从中提取业务异常信息。
[2].利用Xml文档类型的节点实现较好的异常信息封包,需要客户端配合才行,不可取。
怎么办?
既然被SoapException封装,那么就好好研究下SoapException吧。
先看示例: 如果服务器端抛出一个简单异常:Throw New Exception("发生了一些错误!");
那么客户端调用WebMeth会捕获到什么异常信息:
System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Exception: 发生了一些错误!at AYS17Sept2002.Service1.CallFault() in c:\inetpub\wwwroot \AYS17Sept2002\Service1.asmx.vb:line 49 --- End of inner exception stack trace ---
我是在服务器端调用的,先把发布后的webconfig重新配置下,
/configuration/system.web/customErrors/@mode来关闭和开启堆栈信息,默认是RemoteOnly,我们可以设置为:On
[说明: "On" 始终显示自定义(友好的)信息。
"Off" 始终显示详细的 ASP.NET 错误信息。
"RemoteOnly" 只对不在本地 Web 服务器上运行的用户显示自定义(友好的)信息。出于安全目的,建议使用此设置,以便不向远程客户端显示应用程序的详细信息。]
这时客户端捕获到的信息就是:
Server was unable to process request. ---> 发生了一些错误!
恩,不错,但是现在客户端只需要捕获到业务错误信息,该怎么办 ?让客户端用'--->'截取后半部分,太麻烦了.
MSDN上关于SoapException.ServerFaultCode 字段 的解释:指定一个 SOAP 错误代码,该错误代码表示在处理客户端对服务器的调用的过程中出错,但问题不是由消息内容导致的。
备注
例如,当被调用的服务器因网络问题不能响应请求时,就有可能发生erverFaultCode。通常情况下,在出现此类异常的情况下,客户端调用稍后可能会成功。
如果 XML Web services 引发 SoapException 外的其他异常,且客户端使用 SOAP 协议与 XML Web services 通信,则ASP.NET 返回一个 SOAP 错误。客户端计算机上运行的 .NET Framework 将该 SOAP 错误转换成 SoapException,并将 Code 属性 (Property) 设置成 ServerFaultCode,同时在客户端引发该异常。
SoapException 构造函数:
public SoapException (string message,XmlQualifiedName code)
使用指定的异常消息和异常代码初始化 SoapException 类的新实例。那就用这个构造函数测试下吧!抛出如下异常 :
Throw New SoapException( "发生了一些错误!",SoapException .ServerFaultCode);
通过这种方式,客户端将只捕获到message信息,很好.哈哈,达到目标了.
重新测试下这时客户端捕获到的信息就是: 发生了一些错误!
备注:我们项目需要对异常信息进行加密,客户端再解密,只得这么做了.如果不这样处理,客户端捕获到的是"明文-->密文"的形式,如果直接解密则出现错误,反而不能达到错误信息.问题解决了 .好了,有时间还是好好研究下WebService,有太多太多值得学习的.