2

我有一个带有自定义 IErrorHandler 的 REST WCF 服务,这样我就可以在我的服务中捕获所有未捕获的异常并返回自定义错误消息、正确的 Http 状态代码 (500) 并记录错误。

问题是 IErrorHandler 将捕获不是源自我的代码的异常,因此如果我使用无效的 JSON 数据对服务进行 POST,我将得到一个 SerializationException。如果不是我的 IErrorHandler,我将像处理所有其他未捕获的异常一样处理它,该异常将被转换为状态代码为 BadRequest 400 的 WebFaultException。

有没有办法处理这些情况,或者我应该在我的 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);
        }
}
4

2 回答 2

1

我遇到了类似的问题。

我的解决方案是使用命名空间来确定异常的来源。

if (!error.StackTrace.TrimStart().StartsWith("at " + this.GetType().Namespace.Split('.')[0]))
    return;

这适用于我当前的项目。但根据您的项目,它可能不会...

于 2011-11-07T20:17:51.457 回答
0

我认为@RichardBlewett是对的。您将要创建一个自定义异常类并抛出它,在错误处理程序中检查该类型,然后让标准序列化异常正常通过。这对我来说似乎是最好的设计模式。

然后你会得到一个类型安全的异常,如果你删除或更改,错误处理程序代码将不会编译,或者如果你通过 VS 执行,错误处理程序代码将使用类型重构。像这样测试命名空间可能不太可取(尽管非常聪明),因为它在编译时不直接与任何类型相关联。如果您更改名称空间,您将遇到难以追踪的问题。

于 2012-08-29T20:48:11.497 回答