为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
} // 结束 namespaceWeb.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标头?