WCF IErrorHandler 将 FaultException 返回到 SOAP 并将 WebHttpException 返回到 POX 和 Json 端点 [英] WCF IErrorHandler to return FaultException to SOAP and WebHttpException to POX and Json endpoints

查看:57
本文介绍了WCF IErrorHandler 将 FaultException 返回到 SOAP 并将 WebHttpException 返回到 POX 和 Json 端点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组使用 IErrorHandler 包装异常的 SOAP 网络服务,特别是:

I have a set of SOAP webservices that are wrapping exceptions using IErrorHandler, specifically:

public sealed class ErrorHandler : IErrorHandler
{
    public bool HandleError(Exception error)
    {
        return true;
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        // don't wrap existing fault exceptions
        if ((error is FaultException)) return;

        // our basic service fault
        var businessFault = new BusinessFault { FaultMessage = error.Message, FaultReference = "Internal" };

        // Resource based faultReason
        var faultReason = new FaultReason(Properties.Resources.BusinessFaultReason);
        var faultcode = FaultCodeFactory.CreateVersionAwareSenderFaultCode(InternalFaultCodes.BusinessFailure.ToString(), Service.Namespace);

        var faultException = new FaultException<BusinessFault>(
            businessFault,
            faultReason,
            faultcode);

        // Create message fault
        var messageFault = faultException.CreateMessageFault();

        // Create message using Message Factory method
        fault = Message.CreateMessage(version, messageFault, faultException.Action);
    }
}

我现在为 Json 和 Pox 添加了额外的端点,它们可以正常工作,除非发生异常.对于 Json 端点,FaultException 以 XML 形式返回.

I have now added extra endpoints for Json and Pox which work fine, unless an exception occurs. In the case of the Json endpoint the FaultException is returned as XML.

我从其他 SO 帖子中了解到,在 REST 的情况下,我最好抛出 WebHttpException:

I am aware from other SO posts that in the case of REST I would be better throwing a WebHttpException:

throw new WebFaultException<BusinessFault>(detail, HttpStatusCode.BadRequest);

或者覆盖 ProvideFault 中的响应消息属性,因此:

Or overriding the response message properties in ProvideFault, thus:

var wbf = new WebBodyFormatMessageProperty(WebContentFormat.Json);
fault.Properties.Add(WebBodyFormatMessageProperty.Name, wbf);

var rmp = new HttpResponseMessageProperty
{
    StatusCode = System.Net.HttpStatusCode.BadRequest,
    StatusDescription = "See fault object for more information."
};
fault.Properties.Add(HttpResponseMessageProperty.Name, rmp);

然而,MSDN 有一些关于 WebHttpException 的有趣评论,即:

However, MSDN has some interesting remarks about WebHttpException namely:

当使用 WCF REST 端点(WebHttpBinding 和 WebHttpBehavior 或WebScriptEnablingBehavior) 设置响应上的 HTTP 状态代码因此.但是,WebFaultException 可以与非 RE​​ST 一起使用端点并表现得像一个常规的 FaultException.

When using a WCF REST endpoint (WebHttpBinding and WebHttpBehavior or WebScriptEnablingBehavior) the HTTP status code on the response is set accordingly. However, WebFaultException can be used with non-REST endpoints and behaves like a regular FaultException.

使用 WCF REST 端点时,序列化的响应格式故障的确定方式与非故障响应相同.更多有关 WCF REST 格式的信息,请参阅 WCF REST 格式.

When using a WCF REST endpoint, the response format of the serialized fault is determined in the same way as a non-fault response. For more information about WCF REST formatting, see WCF REST Formatting.

因此建议我需要转换我当前的 ProvideFault 方法以提供新的 WebHttpException(包装任何现有的 Exceptions 或 FaultExceptions),然后 SOAP 仍然可以正常工作.

It would suggest therefore that I need to convert my current ProvideFault method to provide a new WebHttpException (wrapping any existing Exceptions or FaultExceptions) and then SOAP would still work as well.

有人想尝试一下它的外观吗(.Net4.0 btw)?我想要一个错误处理程序来统治它们!

Would anyone like to take a stab at what that would look like (.Net4.0 btw)? I want one error handler to rule them all!

推荐答案

在我正在处理的 REST 应用程序中,我创建了一个派生自 WebFaultException 的新类,该类附加了一些附加数据捕获服务异常.在派生类的实例上调用 CreatingMessageFault() 方法让我从错误处理程序的 ProvideFault() 方法返回我选择的异常数据作为 SOAP 错误,让WCF 确定正确的消息格式.

In a REST application I'm working on, I created a new class derived from WebFaultException<T> that attaches some additional data to caught service exceptions. Calling the CreatingMessageFault() method on the instance of the derived class let me return my selected exception data from the ProvideFault() method of the error handler as the SOAP fault, letting WCF determine the correct message format.

我正在使用 webHttpBinding 绑定除某些第三方服务之外的所有服务.

I am using webHttpBinding to bind all but some third-party services.

添加代码示例

public class ErrorHandler : IErrorHandler, IServiceBehavior
{       
    public virtual void ProvideFault( Exception error, MessageVersion version, ref Message fault )
    {
        // Include next level of detail in message, if any.
        MyFaultException myFaultException =
            ((error is MyFaultException) &&
                ((MyFaultException)error).Detail != null)
            ? new MyFaultException(error.Message + " - " +
                    ((MyFaultException)error).Detail.Message, error)
            : new MyFaultException( error.Message, error );
        MessageFault messageFault = myFaultException.CreateMessageFault();
        fault = Message.CreateMessage( version, messageFault, myFaultException.Action );
    }
}

/// <summary>
/// Class used to return exception data from my WCF services.
/// </summary>
/// <remarks>
/// This class is used by a web service to pass exception data back and a
/// data object to the client. This class inherits WebFaultException, which
/// is handled specially by the WCF WebServiceHost2 service class and
/// generates a WebException on the client.
/// </remarks>
public class MyFaultException : WebFaultException<BusinessFault>
{
public class MyFaultException : WebFaultException<BusinessFault>
{
    public MyFaultException(string message)
        : this(HttpStatusCode.BadRequest, message) { }

    public MyFaultException(HttpStatusCode statusCode, string message)
        : base(new BusinessFault(message), statusCode) { }
}

然后在您的服务中,您可以抛出异常以将故障数据传递给您的客户端:

then in your service, you can throw the exception to pass fault data to your client:

        try
        {
            // Successful operation proceeds normally.
        }
        catch (ApplicationException e)
        {
            // Failure generates MyFaultException.
            throw new MyFaultException("Operation failed with " + e.Message);
        }

这篇关于WCF IErrorHandler 将 FaultException 返回到 SOAP 并将 WebHttpException 返回到 POX 和 Json 端点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆