封装SoapException处理Webservice异常
Webservice客户端使用一个WebMethod时,如果WebMethod内部出现异常,不管异常是系统级异常或者自定义的异常,均会被包装为SoapException类型的异常,返回给客户端。 客户端再使用这种SoapException时,无法直接从异常类的属性中提取直接的业务异常信息。
网上看到有同学是做了一个SoapException的Helper类,利用正则表达式的方式,从SoapException的属性做文法分析,从中提取业务异常信息。可是感觉这种方法不是很.Net,而且是不保险的一种做法,如果是自定义异常之类的,在做文法分析时可能会有隐患。而且不能更好的体现错误号。
仔细研究了SoapException之后,发现它有个detail属性,可以利用这个Xml文档类型的节点实现较好的异常信息封包。
步骤如下:
一、(服务端)建立 SoapException 的封包方法
/// <summary>
/// 异常类型
/// </summary>
public enum FaultCode
{
Client = 0,
Server = 1
}
/// <summary>
/// 封装异常为SoapException
/// </summary>
/// <param name="uri">引发异常的方法uri</param>
/// <param name="errorMessage">错误信息</param>
/// <param name="errorNumber">错误号</param>
/// <param name="errorSource">错误源</param>
/// <param name="code">异常类型</param>
/// <returns>封装后的SoapException</returns>
public SoapException RaiseException(
string uri,
string errorMessage,
string errorNumber,
string errorSource,
FaultCode code
)
{
//初始化限定名
XmlQualifiedName faultCodeLocation = null;
//异常类型代码转换
switch (code)
{
case FaultCode.Client:
faultCodeLocation = SoapException.ClientFaultCode;
break;
case FaultCode.Server:
faultCodeLocation = SoapException.ServerFaultCode;
break;
}
//构建异常信息结构体
string strXmlOut = @"<detail>"
+ "<Error>"
+ "<ErrorNumber>" + errorNumber + "</ErrorNumber>"
+ "<ErrorMessage>" + errorMessage + "</ErrorMessage>"
+ "<ErrorSource>" + errorSource + "</ErrorSource>"
+ "</Error>"
+ "</detail>";
//装载为Xml文档
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(strXmlOut);
//实例化SoapException
SoapException soapEx = new SoapException(errorMessage, faultCodeLocation, uri, xmlDoc.DocumentElement);
//返回SoapException
return soapEx;
}
/// 异常类型
/// </summary>
public enum FaultCode
{
Client = 0,
Server = 1
}
/// <summary>
/// 封装异常为SoapException
/// </summary>
/// <param name="uri">引发异常的方法uri</param>
/// <param name="errorMessage">错误信息</param>
/// <param name="errorNumber">错误号</param>
/// <param name="errorSource">错误源</param>
/// <param name="code">异常类型</param>
/// <returns>封装后的SoapException</returns>
public SoapException RaiseException(
string uri,
string errorMessage,
string errorNumber,
string errorSource,
FaultCode code
)
{
//初始化限定名
XmlQualifiedName faultCodeLocation = null;
//异常类型代码转换
switch (code)
{
case FaultCode.Client:
faultCodeLocation = SoapException.ClientFaultCode;
break;
case FaultCode.Server:
faultCodeLocation = SoapException.ServerFaultCode;
break;
}
//构建异常信息结构体
string strXmlOut = @"<detail>"
+ "<Error>"
+ "<ErrorNumber>" + errorNumber + "</ErrorNumber>"
+ "<ErrorMessage>" + errorMessage + "</ErrorMessage>"
+ "<ErrorSource>" + errorSource + "</ErrorSource>"
+ "</Error>"
+ "</detail>";
//装载为Xml文档
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(strXmlOut);
//实例化SoapException
SoapException soapEx = new SoapException(errorMessage, faultCodeLocation, uri, xmlDoc.DocumentElement);
//返回SoapException
return soapEx;
}
二、(服务端)WebMethod的异常处理中调用此方法。例如:
/// <summary>
/// 根据ID读取人员信息
/// </summary>
/// <returns>人员信息类</returns>
[WebMethod(Description = "根据ID读取人员信息")]
public PersonInfo WSReadPersonByID(int ID)
{
try
{
PersonMethod personMethod = new PersonMethod();
return personMethod.ReadPersonByID(ID);
}
catch (System.Exception ex)
{
throw RaiseException(
"WSReadPersonByID",
ex.Message,
"1000",
ex.Source,
FaultCode.Server
);
}
}
/// 根据ID读取人员信息
/// </summary>
/// <returns>人员信息类</returns>
[WebMethod(Description = "根据ID读取人员信息")]
public PersonInfo WSReadPersonByID(int ID)
{
try
{
PersonMethod personMethod = new PersonMethod();
return personMethod.ReadPersonByID(ID);
}
catch (System.Exception ex)
{
throw RaiseException(
"WSReadPersonByID",
ex.Message,
"1000",
ex.Source,
FaultCode.Server
);
}
}
三、(客户端)建立SoapException的信息解析类
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.Web.Services.Protocols;
/// <summary>
/// SoapException 信息解析类
/// </summary>
public class SoapExceptionInfo
{
/// <summary>
/// 错误号
/// </summary>
public string ErrorNumber = string.Empty;
/// <summary>
/// 错误信息
/// </summary>
public string ErrorMessage = string.Empty;
/// <summary>
/// 错误源
/// </summary>
public string ErrorSource = string.Empty;
/// <summary>
/// SoapExceptionInfo构造方法
/// </summary>
public SoapExceptionInfo()
{
}
/// <summary>
/// SoapExceptionInfo构造方法
/// </summary>
/// <param name="soapEx">SoapException</param>
public SoapExceptionInfo(SoapException soapEx)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(soapEx.Detail.OuterXml);
XmlNode categoryNode = doc.DocumentElement.SelectSingleNode("Error");
this.ErrorNumber = categoryNode.SelectSingleNode("ErrorNumber").InnerText;
this.ErrorMessage = categoryNode.SelectSingleNode("ErrorMessage").InnerText;
this.ErrorSource = categoryNode.SelectSingleNode("ErrorSource").InnerText;
}
}
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.Web.Services.Protocols;
/// <summary>
/// SoapException 信息解析类
/// </summary>
public class SoapExceptionInfo
{
/// <summary>
/// 错误号
/// </summary>
public string ErrorNumber = string.Empty;
/// <summary>
/// 错误信息
/// </summary>
public string ErrorMessage = string.Empty;
/// <summary>
/// 错误源
/// </summary>
public string ErrorSource = string.Empty;
/// <summary>
/// SoapExceptionInfo构造方法
/// </summary>
public SoapExceptionInfo()
{
}
/// <summary>
/// SoapExceptionInfo构造方法
/// </summary>
/// <param name="soapEx">SoapException</param>
public SoapExceptionInfo(SoapException soapEx)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(soapEx.Detail.OuterXml);
XmlNode categoryNode = doc.DocumentElement.SelectSingleNode("Error");
this.ErrorNumber = categoryNode.SelectSingleNode("ErrorNumber").InnerText;
this.ErrorMessage = categoryNode.SelectSingleNode("ErrorMessage").InnerText;
this.ErrorSource = categoryNode.SelectSingleNode("ErrorSource").InnerText;
}
}
四、(客户端)使用WebMethod时,使用 SoapException的信息解析类方法
public PersonInfo ReadByID(int id)
{
try
{
WSDemoService ws = new WSDemoService();
ws.Credentials = System.Net.CredentialCache.DefaultCredentials;
return ws.WSReadPersonByID(id);
}
catch (SoapException soapEx)
{
SoapExceptionInfo soapExInfo = new SoapExceptionInfo(soapEx);
throw new System.Exception(soapExInfo.ErrorMessage);
}
catch (Exception ex)
{
throw ex;
}
}
{
try
{
WSDemoService ws = new WSDemoService();
ws.Credentials = System.Net.CredentialCache.DefaultCredentials;
return ws.WSReadPersonByID(id);
}
catch (SoapException soapEx)
{
SoapExceptionInfo soapExInfo = new SoapExceptionInfo(soapEx);
throw new System.Exception(soapExInfo.ErrorMessage);
}
catch (Exception ex)
{
throw ex;
}
}