简体   繁体   English

REST WCF 服务与 IErrorHandler 捕获序列化异常

[英]REST WCF Service with IErrorHandler catches SerializationExceptions

I have a REST WCF service with a custom IErrorHandler, so that I can catch all uncaught exceptions in my service and return a custom error message, a proper Http status code (500) and log the error.我有一个带有自定义 IErrorHandler 的 REST WCF 服务,这样我就可以在我的服务中捕获所有未捕获的异常并返回自定义错误消息、正确的 Z9D4D43DE68F0B3555D5A5EF5DC05BB9Z5 和错误状态代码。

The problem is that the IErrorHandler will catch exceptions not originating from my code, so if I for example make a POST to the service with invalid JSON data, I will get a SerializationException.问题是 IErrorHandler 将捕获不是源自我的代码的异常,因此如果我使用无效的 JSON 数据对服务进行 POST,我将得到一个 SerializationException。 That exception would have been transformed into a WebFaultException with status code BadRequest 400, if it weren't for my IErrorHandler, where I will handle it just like all other uncaught exceptions.如果不是我的 IErrorHandler,我将像处理所有其他未捕获的异常一样处理它,该异常将被转换为状态代码为 BadRequest 400 的 WebFaultException。

Is there a way of dealing with these situations or should I just catch SerializationExceptions in my IErrorHandler and set BadRequest there?有没有办法处理这些情况,或者我应该在我的 IErrorHandler 中捕获 SerializationExceptions 并在那里设置 BadRequest? What other exceptions might orginate from the WCF stack without coming from my code?还有哪些其他异常可能来自 WCF 堆栈而不来自我的代码?

Update: Added my implementation of IErrorHandler.ProvideFault更新:添加了我的 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);
        }
}

I ran into a similar issue.我遇到了类似的问题。

My Solution has been to use the namespace to determine the origin of the exception.我的解决方案是使用命名空间来确定异常的来源。

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

This works in my current project.这适用于我当前的项目。 But depending on your project, it may not...但根据您的项目,它可能不会...

I think @RichardBlewett has it right.我认为@RichardBlewett是对的。 You're going to want to create a custom exception class and throw that, check for that type in the error handler and then let the standard Serialization exception flow through normally.您将要创建一个自定义异常 class 并抛出它,在错误处理程序中检查该类型,然后让标准序列化异常正常通过。 That seems like the best design pattern to me.这对我来说似乎是最好的设计模式。

Then you get a type safe exception that if you remove or change, the error handler code won't compile or will get refactored with the type if you do it via VS.然后你会得到一个类型安全的异常,如果你删除或更改,错误处理程序代码将不会编译,或者如果你通过 VS 执行,错误处理程序代码将使用类型重构。 Testing the namespace like that would probably be less than advisable (though very clever), since it's not directly tied to any type at compile time.像这样测试命名空间可能不太可取(尽管非常聪明),因为它在编译时不直接与任何类型相关联。 If you change namespaces around, you would run into a problem that's difficult to track down.如果您更改名称空间,您将遇到难以追踪的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM