天天看點

化零為整WCF(4) - 異常處理(Exception、FaultException、FaultException、IErrorHandler)

<a href="http://webabcd.blog.51cto.com/1787395/343999" target="_blank">[索引頁]</a>

化零為整WCF(4) - 異常處理(Exception、FaultException、FaultException&lt;T&gt;、IErrorHandler)

介紹

WCF(Windows Communication Foundation) - 異常處理:一般Exception的處理,FaultException和FaultException&lt;T&gt;的抛出和處理,使用IErrorHandler處理異常。

示例

1、服務

IHello.cs

using System; 

using System.Collections.Generic; 

using System.Linq; 

using System.Text; 

using System.ServiceModel; 

namespace WCF.ServiceLib.Exception 

        /// &lt;summary&gt; 

        /// IHello接口 

        /// &lt;/summary&gt; 

        [ServiceContract] 

        public interface IHello 

        { 

                /// &lt;summary&gt; 

                /// 抛出Exception異常 

                /// &lt;/summary&gt; 

                [OperationContract] 

                void HelloException(); 

                /// 抛出FaultException異常 

                void HelloFaultException(); 

                /// 抛出FaultException&lt;T&gt;異常 

                [FaultContract(typeof(FaultMessage))] 

                void HelloFaultExceptionGeneric(); 

                /// IErrorHandler處理異常 

                void HelloIErrorHandler(); 

        } 

}

FaultMessage.cs

using System.Runtime.Serialization; 

        /// 錯誤資訊實體類(用于錯誤契約FaultContract) 

        [DataContract] 

        public class FaultMessage 

                /// 錯誤資訊 

                [DataMember] 

                public string Message { get; set; } 

                /// 錯誤代碼 

                public int ErrorCode { get; set; } 

FaultErrorHandler.cs

using System.ServiceModel.Dispatcher; 

using System.Configuration; 

using System.ServiceModel.Channels; 

        /// 自定義錯誤處理器(繼承自System.ServiceModel.Dispatcher.IErrorHandler) 

        public class FaultErrorHandler : IErrorHandler 

                /// 在異常傳回給用戶端之後被調用 

                /// &lt;param name="error"&gt;異常&lt;/param&gt; 

                /// &lt;returns&gt;&lt;/returns&gt; 

                public bool HandleError(System.Exception error) 

                { 

                        System.IO.StreamWriter sw = new System.IO.StreamWriter(@"C:\WCF_Log.txt", true); 

                        sw.Write("IErrorHandler - HandleError測試。錯誤類型:{0};錯誤資訊:{1}", error.GetType().ToString(), error.Message); 

                        sw.WriteLine(); 

                        sw.Flush(); 

                        sw.Close(); 

                        // true - 已處理 

                        return true; 

                } 

                /// 在異常發生後,異常資訊傳回前被調用 

                /// &lt;param name="version"&gt;SOAP版本&lt;/param&gt; 

                /// &lt;param name="fault"&gt;傳回給用戶端的錯誤資訊&lt;/param&gt; 

                public void ProvideFault(System.Exception error, System.ServiceModel.Channels.MessageVersion version, ref System.ServiceModel.Channels.Message fault) 

                        if (error is System.IO.IOException) 

                        { 

                                FaultException ex = new FaultException("IErrorHandler - ProvideFault測試"); 

                                MessageFault mf = ex.CreateMessageFault(); 

                                fault = Message.CreateMessage(version, mf, ex.Action); 

                                // InvalidOperationException error = new InvalidOperationException("An invalid operation has occurred."); 

                                // MessageFault mfault = MessageFault.CreateFault(new FaultCode("Server", new FaultCode(String.Format("Server.{0}", error.GetType().Name))), new FaultReason(error.Message), error); 

                                // FaultException fe = FaultException.CreateFault(mfault, typeof(InvalidOperationException)); 

                        } 

Hello.cs

using System.ServiceModel.Description; 

        /// Hello類 

        public class Hello : IHello, IDisposable, IServiceBehavior    

                public void HelloException() 

                        throw new System.Exception("抛出Exception異常"); 

                public void HelloFaultException() 

                        throw new FaultException("抛出FaultException異常", new FaultCode("服務")); 

                public void HelloFaultExceptionGeneric() 

                        throw new FaultException&lt;FaultMessage&gt;(new FaultMessage { Message = "抛出FaultException&lt;T&gt;異常", ErrorCode = -1 }, "為了測試FaultException&lt;T&gt;用的"); 

                public void HelloIErrorHandler() 

                        throw new System.IO.IOException("抛出異常,用IErrorHandler處理"); 

                /// 實作IDisposable接口的Dispose()方法 

                public void Dispose() 

                /// 為契約增加自定義綁定參數 

                /// &lt;param name="serviceDescription"&gt;服務描述&lt;/param&gt; 

                /// &lt;param name="serviceHostBase"&gt;服務宿主&lt;/param&gt; 

                /// &lt;param name="endpoints"&gt;服務端點&lt;/param&gt; 

                /// &lt;param name="bindingParameters"&gt;需要增加的自定義綁定參數&lt;/param&gt; 

                public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection&lt;ServiceEndpoint&gt; endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) 

                /// runtime時修改屬性值或增加自定義擴充對象 

                public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 

                        IErrorHandler handler = new FaultErrorHandler(); 

                        foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers) 

                                // 增加錯誤處理器 

                                dispatcher.ErrorHandlers.Add(handler); 

                /// 檢查服務描述和服務宿主,以确認服務可以成功運作 

                public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 

2、宿主

Hello.svc

&lt;%@ ServiceHost Language="C#" Debug="true" Service="WCF.ServiceLib.Exception.Hello" %&gt;

Web.config

&lt;?xml version="1.0"?&gt; 

&lt;configuration&gt; 

    &lt;system.serviceModel&gt; 

        &lt;behaviors&gt; 

            &lt;serviceBehaviors&gt; 

                &lt;behavior name="ExceptionBehavior"&gt; 

                    &lt;!--httpGetEnabled - 使用get方式提供服務--&gt; 

                    &lt;serviceMetadata httpGetEnabled="true" /&gt; 

                    &lt;serviceDebug includeExceptionDetailInFaults="true"/&gt; 

                &lt;/behavior&gt; 

            &lt;/serviceBehaviors&gt; 

        &lt;/behaviors&gt; 

        &lt;services&gt; 

            &lt;!--name - 提供服務的類名--&gt; 

            &lt;!--behaviorConfiguration - 指定相關的行為配置--&gt; 

            &lt;service name="WCF.ServiceLib.Exception.Hello" behaviorConfiguration="ExceptionBehavior"&gt; 

                &lt;!--address - 服務位址--&gt; 

                &lt;!--binding - 通信方式--&gt; 

                &lt;!--contract - 服務契約--&gt; 

                &lt;endpoint address="" binding="wsHttpBinding" contract="WCF.ServiceLib.Exception.IHello" /&gt; 

            &lt;/service&gt; 

        &lt;/services&gt; 

    &lt;/system.serviceModel&gt; 

&lt;/configuration&gt;

3、用戶端

Hello.aspx

&lt;%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Hello.aspx.cs" 

        Inherits="Exception_Hello" Title="異常處理(Exception、FaultException、FaultException&lt;T&gt;、IErrorHandler)" %&gt; 

&lt;asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server"&gt; 

&lt;/asp:Content&gt; 

&lt;asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server"&gt; 

        &lt;div&gt; 

                &lt;asp:Label ID="lblMsg" runat="server" /&gt; 

        &lt;/div&gt; 

        &lt;br /&gt; 

                &lt;asp:Button ID="btnHelloException" runat="server" Text="HelloException" OnClick="btnHelloException_Click" /&gt; 

                &lt;asp:Button ID="btnHelloFaultException" runat="server" Text="HelloFaultException" 

                        OnClick="btnHelloFaultException_Click" /&gt; 

                &lt;asp:Button ID="btnHelloFaultExceptionGeneric" runat="server" Text="HelloFaultExceptionGeneric" 

                        OnClick="btnHelloFaultExceptionGeneric_Click" /&gt; 

                &lt;asp:Button ID="btnHelloIErrorHandler" runat="server" Text="HelloIErrorHandler" OnClick="btnHelloIErrorHandler_Click" /&gt; 

&lt;/asp:Content&gt;

Hello.aspx.cs

using System.Collections; 

using System.Data; 

using System.Web; 

using System.Web.Security; 

using System.Web.UI; 

using System.Web.UI.HtmlControls; 

using System.Web.UI.WebControls; 

using System.Web.UI.WebControls.WebParts; 

using System.Xml.Linq; 

public partial class Exception_Hello : System.Web.UI.Page 

        protected void Page_Load(object sender, EventArgs e) 

        protected void btnHelloException_Click(object sender, EventArgs e) 

                ExceptionService.HelloClient proxy = new ExceptionService.HelloClient(); 

                try 

                        proxy.HelloException(); 

                catch (Exception ex) 

                        lblMsg.Text = ex.Message; 

                finally 

                        try 

                                proxy.Close(); 

                        catch (Exception ex) 

                                lblMsg.Text += "&lt;br /&gt;" + ex.Message; 

        protected void btnHelloFaultException_Click(object sender, EventArgs e) 

                        proxy.HelloFaultException(); 

                catch (FaultException ex) 

                        lblMsg.Text = string.Format("錯誤編碼:{0};錯誤原因:{1}", 

                                ex.Code.Name, 

                                ex.Reason.ToString()); 

                        proxy.Close(); 

        protected void btnHelloFaultExceptionGeneric_Click(object sender, EventArgs e) 

                        proxy.HelloFaultExceptionGeneric(); 

                catch (System.ServiceModel.FaultException&lt;ExceptionService.FaultMessage&gt; ex) 

                        lblMsg.Text = string.Format("錯誤代碼:{0};錯誤資訊:{1};錯誤原因:{2}", 

                                ex.Detail.ErrorCode.ToString(), 

                                ex.Detail.Message, 

        protected void btnHelloIErrorHandler_Click(object sender, EventArgs e) 

                        proxy.HelloIErrorHandler(); 

                        System.ServiceModel.FaultException faultException = ex as System.ServiceModel.FaultException; 

                        if (faultException != null) 

                                lblMsg.Text = string.Format("錯誤資訊:{0}", faultException.Message); 

                        else 

                                lblMsg.Text = ex.ToString(); 

        &lt;client&gt; 

            &lt;!--address - 服務位址--&gt; 

            &lt;!--binding - 通信方式--&gt; 

            &lt;!--contract - 服務契約--&gt; 

            &lt;endpoint address="http://localhost:3502/ServiceHost/Exception/Hello.svc" binding="wsHttpBinding" contract="ExceptionService.IHello" /&gt; 

        &lt;/client&gt; 

運作結果:

單擊"btnHelloException"後顯示

抛出Exception異常

The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state. 

單擊"btnHelloFaultException"後顯示

錯誤編碼:服務;錯誤原因:抛出FaultException異常

單擊"btnHelloFaultExceptionGeneric"後顯示

錯誤代碼:-1;錯誤資訊:抛出FaultException異常;錯誤原因:為了測試FaultException用的

單擊"btnHelloIErrorHandler"後顯示

錯誤資訊:IErrorHandler - ProvideFault測試

OK

<a href="http://down.51cto.com/data/100781" target="_blank">[源碼下載下傳]</a>

     本文轉自webabcd 51CTO部落格,原文連結:http://blog.51cto.com/webabcd/344112,如需轉載請自行聯系原作者