WCF SOAP 全局异常


先看下客户端捕获异常情况,以下异常基本上看不懂。参照NLayerApp 进行了全局异常捕获。
image 

一. DistributedServices.Core  结构如下
image

1.1 DefaultErrorHandler


using
System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel.Dispatcher; using System.ServiceModel.Channels; using System.ServiceModel; namespace DistributedServices.Core { public class DefaultErrorHandler : IErrorHandler { /// <summary> /// 启用错误相关处理并返回一个值,该值指示调度程序在某些情况下是否中止会话和实例上下文。 /// </summary> /// <param name="error">处理过程中引发的异常</param> /// <returns></returns> public bool HandleError(Exception error) { //不终止会话和实例上下文 return true; } /// <summary> /// 启用创建从服务方法过程中的异常返回的自定义SOAP错误 /// </summary> /// <param name="error">服务操作过程中引发的异常 </param> /// <param name="version">消息的 SOAP 版本</param> /// <param name="fault">双工情况下,返回到客户端或服务的通信单元对象 </param> public void ProvideFault(Exception error, MessageVersion version, ref Message fault) { //var faultException = error is FaultException ? // (FaultException)error : new FaultException(error.Message); //MessageFault messageFault = faultException.CreateMessageFault(); //fault = Message.CreateMessage(version, messageFault, faultException.Action); if (error is FaultException<ServiceError>) { MessageFault messageFault = ((FaultException<ServiceError>)error).CreateMessageFault(); //propagate FaultException fault = Message.CreateMessage(version, messageFault, ((FaultException<ServiceError>)error).Action); } else { //create service error ServiceError defaultError = new ServiceError() { ErrorMessage = "错误" }; //Create fault exception and message fault FaultException<ServiceError> defaultFaultException = new FaultException<ServiceError>(defaultError); MessageFault defaultMessageFault = defaultFaultException.CreateMessageFault(); //propagate FaultException fault = Message.CreateMessage(version, defaultMessageFault, defaultFaultException.Action); } } } }


1.2 ServiceError


using
System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.Serialization; namespace DistributedServices.Core { [DataContract] public class ServiceError { /// <summary> /// Error message that flow to client services /// </summary> [DataMember(Name = "ErrorMessage")] public string ErrorMessage { get; set; } } }


1.3 ServiceErrorHandlerBehavior


using
System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel.Description; using System.ServiceModel; using System.ServiceModel.Dispatcher; using System.Collections.ObjectModel; using System.ServiceModel.Channels; namespace DistributedServices.Core { [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public sealed class ServiceErrorHandlerBehavior : Attribute, IServiceBehavior { /// <summary> /// 用于更改运行时属性值或插入自定义扩展对象(例如错误处理程序、消息或参数拦截器、安全扩展以及其他自定义扩展对象)。 /// </summary> /// <param name="serviceDescription"> 服务说明</param> /// <param name="serviceHostBase"> 当前正在生成的宿主 </param> public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { if (serviceHostBase != null && serviceHostBase.ChannelDispatchers.Any()) { foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers) dispatcher.ErrorHandlers.Add(new DefaultErrorHandler()); } } public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { //当前拓展机制不适用 } public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { //当前拓展机制不适用 } } }


二 服务设计

2.1 接口如下

 
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Web; using System.Text; using DistributedServices.Core; namespace WcfService1 { [ServiceContract] public interface IService1 { [OperationContract] //这个是让客户端识别ServiceError,否则异常直接捕获到Exception,捕获不到FaultException [FaultContract(typeof(ServiceError))] string GetData(int value); [OperationContract] CompositeType GetDataUsingDataContract(CompositeType composite); // TODO: Add your service operations here } [DataContract] public class CompositeType { bool boolValue = true; string stringValue = "Hello "; [DataMember] public bool BoolValue { get { return boolValue; } set { boolValue = value; } } [DataMember] public string StringValue { get { return stringValue; } set { stringValue = value; } } } }


2.2 接口服务


using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Web; using System.Text; using DistributedServices.Core; namespace WcfService1 { //以下Attribute需要设置,否则直接走到Exception [ServiceErrorHandlerBehavior()] public class Service1 : IService1 { public string GetData(int value) { throw new NotImplementedException(); } public CompositeType GetDataUsingDataContract(CompositeType composite) { if (composite == null) { throw new ArgumentNullException("composite"); } if (composite.BoolValue) { composite.StringValue += "Suffix"; } return composite; } } }


结果如下
image 

测试代码下载

posted @ 2014-12-30 16:38  kfsmqoo  阅读(229)  评论(0编辑  收藏  举报