2

我有一个看起来像这样的网络服务:

[ServiceContract]
public class MyService
{
   [OperationContract]
   public void BreakStuff()
   {
      throw new MyException();
   }
}

它现在不是一个非常强大的网络服务,但你看 - 它会很棒!

如果我调用,WCF 会捕获异常,返回 HTTP 500,如果设置为 true BreakStuff(),则可以选择吐出序列化堆栈跟踪。IncludeExceptionDetailsInFaults我想覆盖此行为并吐出我自己的自定义错误消息对象,并返回 HTTP 200。我想这样做是因为我认为在某些情况下抛出异常比用try/catch块乱扔代码更干净web 方法返回某种Result对象。

我所做的是我自己的IDispatchMessageFormatter,它有合同:

public interface IDispatchMessageFormatter
{
   void DeserializeRequest(Message message, object[] parameters);
   Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result);
}

SerializeReply为正常的 HTTP 200 响应调用,但是如果 web 方法抛出异常,WCF 永远不会调用SerializeReply,所以我没有机会控制响应输出。

WCF 是否提供自定义错误响应的能力?

4

1 回答 1

2

您可以通过实现IErrorHandler接口来实现自定义错误处理程序。我过去曾使用这种方法以 JSON 格式返回自定义错误信息。在ProvideFault方法中,您还可以更改响应代码。下面是我使用过的一种方法的示例。

public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{   
    fault = GetJsonResponseFromException(version, error);
    ConfigureMessageFormat(ref fault);
    ConfigureHttpReponse(ref fault, error);
}

protected virtual void ConfigureMessageFormat(ref Message fault)
{
    var formatting =
      new WebBodyFormatMessageProperty(WebContentFormat.Json);
    fault.Properties.Add(WebBodyFormatMessageProperty.Name, formatting);
}

protected virtual void ConfigureHttpReponse(ref Message fault, Exception error)
{
    var exception = error as WebFaultException<ServiceFault>;
    var statusCode = HttpStatusCode.InternalServerError;
    var description = HttpWorkerRequest
        .GetStatusDescription(Convert.ToInt32(statusCode));

    if (exception != null)
    {
        statusCode = exception.StatusCode;
        description = exception.Reason.Translations[0].Text;
    }

    var httpResponse = new HttpResponseMessageProperty()
    {
        StatusCode = statusCode,
        StatusDescription = description
    };

    httpResponse.Headers[HttpResponseHeader.ContentType] = "application/json";
    fault.Properties.Add(HttpResponseMessageProperty.Name, httpResponse);
}
于 2012-11-29T05:08:23.373 回答