C#为WCF服务实现IErrorHandler
示例
为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错误处理程序以非OKHTTP代码返回JSON响应?
如何设置HttpClient请求的Content-Type标头?