天天看点

化零为整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,如需转载请自行联系原作者