我有一个看起来像这样的网络服务:
[ServiceContract]
public class MyService
{
[OperationContract]
public void BreakStuff()
{
throw new MyException();
}
}
现在它不是一个非常强大的网络服务,但你看 - 它会很棒!
如果我调用BreakStuff()
,WCF会捕获异常,返回HTTP 500并可选择在IncludeExceptionDetailsInFaults
设置为true时吐出序列化堆栈跟踪。我想重写此行为并吐出我自己的自定义错误消息对象,并返回HTTP 200.我想这样做是因为我认为在某些情况下抛出异常是 cleaner 而不是乱丢代码 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是否提供自定义错误响应的功能?
答案 0 :(得分: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);
}