Webservice用戶端使用一個WebMethod時,如果WebMethod内部出現異常,不管異常是系統級異常或者自定義的異常,均會被包裝為SoapException類型的異常,傳回給用戶端。 用戶端再使用這種SoapException時,無法直接從異常類的屬性中提取直接的業務異常資訊。
網上看到有同學是做了一個SoapException的Helper類,利用正規表達式的方式,從SoapException的屬性做文法分析,從中提取業務異常資訊。可是感覺這種方法不是很.Net,而且是不保險的一種做法,如果是自定義異常之類的,在做文法分析時可能會有隐患。而且不能更好的展現錯誤号。
仔細研究了SoapException之後,發現它有個detail屬性,可以利用這個Xml文檔類型的節點實作較好的異常資訊封包。
步驟如下:
一、(服務端)建立 SoapException 的封包方法
/// <summary>
/// 異常類型
/// </summary>
public enum FaultCode
{
Client = 0,
Server = 1
}
/// 封裝異常為SoapException
/// <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;
}
//建構異常資訊結構體
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的異常進行中調用此方法。例如:
/// 根據ID讀取人員資訊
/// <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
{
/// 錯誤号
public string ErrorNumber = string.Empty;
/// 錯誤資訊
public string ErrorMessage = string.Empty;
/// 錯誤源
public string ErrorSource = string.Empty;
/// SoapExceptionInfo構造方法
public SoapExceptionInfo()
/// <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)
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;