天天看點

封裝SoapException處理Webservice異常

      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;