封装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;
    }

二、(服务端)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
                                );
        }
    }

三、(客户端)建立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;
    }
}

四、(客户端)使用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;
        }
    }
posted on 2008-02-28 01:21  网际浪人  阅读(15369)  评论(3编辑  收藏  举报