为WCF服务实现IErrorHandler是集中错误处理和日志记录的好方法。此处显示的实现应捕获由于调用您的WCF服务之一而引发的任何未处理的异常。此示例还显示了如何返回自定义对象,以及如何返回JSON而不是默认XML。
实现IErrorHandler:
using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; using System.Runtime.Serialization.Json; using System.ServiceModel; using System.ServiceModel.Web; namespace BehaviorsAndInspectors { public class ErrorHandler : IErrorHandler { public bool HandleError(Exception ex) { // 在这里记录例外 return true; } // 结束 public void ProvideFault(Exception ex, MessageVersion version, ref Message fault) { // 获取当前上下文的传出响应部分 var response = WebOperationContext.Current.OutgoingResponse; // 设置默认的http状态代码 response.StatusCode= HttpStatusCode.InternalServerError; // 添加指定我们正在使用JSON的ContentType标头 response.ContentType= new MediaTypeHeaderValue("application/json").ToString(); // 使用BaseDataResponseContract创建返回的故障消息(注意ref参数) fault = Message.CreateMessage( version, string.Empty, new CustomReturnType { ErrorMessage = "发生未处理的异常!" }, new DataContractJsonSerializer(typeof(BaseDataResponseContract), new List<Type> { typeof(BaseDataResponseContract) })); if (ex.GetType() == typeof(VariousExceptionTypes)) { // 您可能想在这里捕获不同类型的异常,并以不同的方式处理它们 } // 告诉WCF使用JSON编码而不是默认XML var webBodyFormatMessageProperty = new WebBodyFormatMessageProperty(WebContentFormat.Json); fault.Properties.Add(WebBodyFormatMessageProperty.Name, webBodyFormatMessageProperty); } // 结束 } // 结束 class } // 结束 namespace
在此示例中,我们将处理程序附加到服务行为。您也可以通过类似的方式将此附加到IEndpointBehavior,IContractBehavior或IOperationBehavior。
附加到服务行为:
using System; using System.Collections.ObjectModel; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Configuration; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; namespace BehaviorsAndInspectors { public class ErrorHandlerExtension : BehaviorExtensionElement, IServiceBehavior { public override Type BehaviorType { get { return GetType(); } } protected override object CreateBehavior() { return this; } private IErrorHandler GetInstance() { return new ErrorHandler(); } void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { } // 结束 void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { var errorHandlerInstance = GetInstance(); foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers) { dispatcher.ErrorHandlers.Add(errorHandlerInstance); } } void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } // 结束 } // 结束 class } // 结束 namespace
Web.config中的配置:
... <system.serviceModel> <services> <service name="WebServices.MyService"> <endpoint binding="webHttpBinding" contract="WebServices.IMyService" /> </service> </services> <extensions> <behaviorExtensions> <!-- This extension if for the WCF Error Handling--> <add name="ErrorHandlerBehavior" type="WebServices.BehaviorsAndInspectors.ErrorHandlerExtensionBehavior, WebServices, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> </behaviorExtensions> </extensions> <behaviors> <serviceBehaviors> <behavior> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="true"/> <ErrorHandlerBehavior /> </behavior> </serviceBehaviors> </behaviors> .... </system.serviceModel> ...
这里有一些链接可能对该主题有所帮助:
https://msdn.microsoft.com/zh-CN/library/system.servicemodel.dispatcher.ierrorhandler(v=vs.100).aspx
http://www.brainthud.com/cards/5218/25441/which-four-behavior-interfaces-exist-for-interacting-with-a-service-or-client-description-what-methods-do-they-实施和
其他例子:
HTTP状态代码为401时,IErrorHandler返回错误的消息正文
IErrorHandler似乎没有处理WCF中的错误。
如何使自定义WCF错误处理程序以非OK HTTP代码返回JSON响应?
如何设置HttpClient请求的Content-Type标头?