我有一个带有自定义IErrorHandler的REST WCF服务,因此我可以捕获服务中所有未捕获的异常,并返回自定义错误消息,正确的Http状态代码(500)并记录错误。
问题是IErrorHandler会捕获不是源自我的代码的异常,所以如果我使用无效的JSON数据对服务进行POST,我将得到一个SerializationException。该异常将被转换为状态代码为BadRequest 400的WebFaultException,如果它不适用于我的IErrorHandler,我将处理它,就像所有其他未捕获的异常一样。
有没有办法处理这些情况,或者我应该只在我的IErrorHandler中捕获SerializationExceptions并在那里设置BadRequest?如果没有来自我的代码,可能会从WCF堆栈中获取哪些其他异常?
更新:添加了我的IErrorHandler.ProvideFault实现
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
Guid loggingId = Guid.NewGuid();
error.Data["ExceptionLoggingId"] = loggingId;
if (error is SecurityTokenException)
{
fault = Message.CreateMessage(version, string.Empty, String.Format("{0}. The error identifier is {1}", error.Message, loggingId), new DataContractJsonSerializer(typeof(string)));
fault.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Json));
webOperationContextWrapper.SetOutgoingResponseStatusCode(HttpStatusCode.Unauthorized);
}
else
{
if (error is SerializationException)
{
// TODO: What if the SerializationException originates from within the service?
// SerializationException due to malformed JSON
return;
}
fault = Message.CreateMessage(version, string.Empty, String.Format("An unknown error has occurred. The error identifier is {0}", loggingId), new DataContractJsonSerializer(typeof(string)));
fault.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Json));
webOperationContextWrapper.SetOutgoingResponseStatusCode(HttpStatusCode.InternalServerError);
}
}
答案 0 :(得分:1)
我遇到了类似的问题。
我的解决方案一直是使用命名空间来确定异常的来源。
if (!error.StackTrace.TrimStart().StartsWith("at " + this.GetType().Namespace.Split('.')[0]))
return;
这适用于我目前的项目。但根据你的项目,它可能不会......
答案 1 :(得分:0)
我认为@RichardBlewett是对的。您将要创建一个自定义异常类并抛出它,在错误处理程序中检查该类型,然后让标准的序列化异常正常流动。这对我来说似乎是最好的设计模式。
然后你会得到一个类型安全的异常,如果你删除或更改,错误处理程序代码将无法编译,或者如果你通过VS进行重构,它将被重构。像这样测试命名空间可能不太合适(虽然非常聪明),因为它在编译时没有直接绑定到任何类型。如果更改名称空间,则会遇到难以追踪的问题。