WCF IErrorHandler扩展未返回指定的Fault

希望有一些WCF向导可以在这里发现我的错误。

我试图通过RESTful JSON WCF服务上基于IErrorHandler的behaviorExtension设置全局error handling程序。 该方法装饰如下:

[OperationContract] [WebGet(UriTemplate = "screens/info", ResponseFormat = WebMessageFormat.Json)] 

IErrorHandler实现是:

 public class ErrorHandler : IErrorHandler { public void ProvideFault(Exception error, MessageVersion version, ref Message fault) { var error = new JsonError { Message = error.Message, FaultCode = -1, StackTrace = error.StackTrace }; fault = Message.CreateMessage(version, "", ideaScreeningError, new DataContractJsonSerializer( ideaScreeningError.GetType())); // tell WCF to use JSON encoding rather than default XML var wbf = new WebBodyFormatMessageProperty(WebContentFormat.Json); fault.Properties.Add(WebBodyFormatMessageProperty.Name, wbf); //Modify response var rmp = new HttpResponseMessageProperty { StatusCode = HttpStatusCode.BadRequest, StatusDescription = "Bad Request" }; fault.Properties.Add(HttpResponseMessageProperty.Name, rmp); } public bool HandleError(Exception error) { return true; } } 

我可以validation(通过断点)正在调用扩展并正在执行。 当我在浏览器中查看AJAX调用的结果时,我可以看到WCF仍然返回500内部服务器错误,而不是我在error handling程序中指定的错误详细信息。

如果我更改了在WCF方法中抛出的exception类型,那些会反映在浏览器的结果中,所以我可以推测WCF正在做一些事情来处理exception并在内部返回一些东西。

我如何让它停止!?

编辑

我正在添加自定义行为元素:

 public class ErrorBehaviorElement : BehaviorExtensionElement { protected override object CreateBehavior() { return new ErrorBehavior(); } public override Type BehaviorType { get { return typeof(ErrorBehavior); } } } 

和行为:

 internal class ErrorBehavior : WebHttpBehavior { protected override void AddServerErrorHandlers(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { // clear default error handlers. endpointDispatcher.ChannelDispatcher.ErrorHandlers.Clear(); // add the Json error handler. endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add( new ErrorHandler()); } } 

这里的问题在于WCF Rest Starter Kit(由于我没有启动这个项目,我没有意识到它正在使用中),更具体地说是WebServiceHost2 。 我在Reflector中打开了ServiceHost,在OnOpening()找到了这段可爱的小代码:

 if (endpoint.Behaviors.Find() != null) { endpoint.Behaviors.Remove(); WebHttpBehavior2 item = new WebHttpBehavior2(); // other code omitted endpoint.Behaviors.Add(item); } 

如您所见,无论您想要添加到端点的行为是什么,只要它inheritance自WebHttpBehavior,Rest Start Kit组件就会劫持您的处理程序,将其删除,并将其替换为自己的处理程序。

请记住,WebHttpBehavior2也inheritance自WebHttBehavior,因此inheritance自我的扩展中的WebHttpBehavior2没有任何帮助。

第一步是创建一个新的WebSeriveHost,它派生自WebServiceHost2并覆盖OnOpening()并重新劫持Rest Starter Kit从我这里偷走的东西:

 if(endpoint.Behaviors.Find() != null) { endpoint.Behaviors.Remove(); var item = ErrorBehavior(); // other code endpoint.Behaviors.Add(item); } 

然后创建一个返回我的自定义WebServiceHost类型的新WebServiceHostFactory。

不要忘记设置响应的ContentType:

 rmp.Headers[HttpResponseHeader.ContentType] = "application/json"; 

根据评论我会尝试删除常见的webHttpBehavior。 您已经定义了自己从webHttp派生的行为。 没有理由在您的服务配置中有两个webHttp行为。 此外,webHttp行为添加了自己的error handling程序,其行为与您描述的完全相同。 也许它没有用,但你可以尝试一下。