.NET WCF 错误生成不正确的 SOAP 1.1 错误代码值 [英] .NET WCF faults generating incorrect SOAP 1.1 faultcode values

查看:19
本文介绍了.NET WCF 错误生成不正确的 SOAP 1.1 错误代码值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 FaultException 和 FaultException;确定我们应用程序中的最佳使用模式.我们需要支持 WCF 以及非 WCF 服务消费者/客户端,包括 SOAP 1.1 和 SOAP 1.2 客户端.

I am experimenting with using the FaultException and FaultException<T> to determine the best usage pattern in our applications. We need to support WCF as well as non-WCF service consumers/clients, including SOAP 1.1 and SOAP 1.2 clients.

仅供参考:将 FaultExceptions 与 wsHttpBinding 结合使用会产生 SOAP 1.2 语义,而将 FaultExceptions 与 basicHttpBinding 结合使用会产生 SOAP 1.1 语义.

FYI: using FaultExceptions with wsHttpBinding results in SOAP 1.2 semantics whereas using FaultExceptions with basicHttpBinding results in SOAP 1.1 semantics.

我正在使用以下代码抛出一个 FaultException:

I am using the following code to throw a FaultException<FaultDetails>:

  throw new FaultException<FaultDetails>(
      new FaultDetails("Throwing FaultException<FaultDetails>."),
      new FaultReason("Testing fault exceptions."),
      FaultCode.CreateSenderFaultCode(new FaultCode("MySubFaultCode"))
      );

FaultDetails 类只是一个简单的测试类,它包含一个字符串Message"属性,如下所示.

The FaultDetails class is just a simple test class that contains a string "Message" property as you can see below.

当使用 wsHttpBinding 时,响应是:

When using wsHttpBinding the response is:

<?xml version="1.0" encoding="utf-16"?>
<Fault xmlns="http://www.w3.org/2003/05/soap-envelope">
<Code>
  <Value>Sender</Value>
  <Subcode>
    <Value>MySubFaultCode</Value>
  </Subcode>
</Code>
<Reason>
  <Text xml:lang="en-US">Testing fault exceptions.</Text>
</Reason>
<Detail>
  <FaultDetails xmlns="http://schemas.datacontract.org/2004/07/ClassLibrary" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Message>Throwing FaultException&lt;FaultDetails&gt;.</Message>
  </FaultDetails>
</Detail>

根据 SOAP 1.2 规范,这看起来是正确的.主/根代码"是发件人",其子代码"为MySubFaultCode".如果服务使用者/客户端使用 WCF,客户端的 FaultException 也会模仿相同的结构,faultException.Code.Name 为Sender",faultException.Code.SubCode.Name 为MySubFaultCode".

This looks right according to the SOAP 1.2 specs. The main/root "Code" is "Sender", which has a "Subcode" of "MySubFaultCode". If the service consumer/client is using WCF the FaultException on the client side also mimics the same structure, with the faultException.Code.Name being "Sender" and faultException.Code.SubCode.Name being "MySubFaultCode".

使用 basicHttpBinding 时,响应为:

When using basicHttpBinding the response is:

<?xml version="1.0" encoding="utf-16"?>
<s:Fault xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <faultcode>s:MySubFaultCode</faultcode>
  <faultstring xml:lang="en-US">Testing fault exceptions.</faultstring>
  <detail>
    <FaultDetails xmlns="http://schemas.datacontract.org/2004/07/ClassLibrary" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <Message>Throwing FaultException&lt;FaultDetails&gt;.</Message>
    </FaultDetails>
  </detail>
</s:Fault>

这看起来不对.查看 SOAP 1.1 规范,当我使用 FaultCode.CreateSenderFaultCode(new FaultCode("MySubFaultCode")) 时,我期望看到故障代码"的值为s:Client.MySubFaultCode".WCF 客户端也获得了不正确的结构.faultException.Code.Name 是MySubFaultCode"而不是Sender",并且 faultException.Code.SubCode 是 null 而不是 faultException.Code.SubCode.Name 是MySubFaultCode".此外,faultException.Code.IsSenderFault 为假.

This does not look right. Looking at the SOAP 1.1 specs, I was expecting to see the "faultcode" to have a value of "s:Client.MySubFaultCode" when I use FaultCode.CreateSenderFaultCode(new FaultCode("MySubFaultCode")). Also a WCF client gets an incorrect structure. The faultException.Code.Name is "MySubFaultCode" instead of being "Sender", and the faultException.Code.SubCode is null instead of faultException.Code.SubCode.Name being "MySubFaultCode". Also, the faultException.Code.IsSenderFault is false.

使用FaultCode.CreateReceiverFaultCode(new FaultCode("MySubFaultCode"))时的类似问题:

Similar problem when using FaultCode.CreateReceiverFaultCode(new FaultCode("MySubFaultCode")):

  • 在 SOAP 1.2 中按预期工作
  • 生成s:MySubFaultCode"而不是s:Server.MySubFaultCode",并且对于 SOAP 1.1,faultException.Code.IsReceiverFault 为 false

此项目也由其他人发布在 http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=669420&SiteID=1 2006 年,没有人回答.我发现很难相信还没有人遇到过这种情况.

This item was also posted by someone else on http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=669420&SiteID=1 in 2006 and no one has answered it. I find it very hard to believe that no one has run into this, yet.

有人遇到类似问题:http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=3883110&SiteID=1&mode=1

Microsoft Connect 错误:https://connect.microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=367963

Microsoft Connect bug: https://connect.microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=367963

故障应该如何工作的描述:http://blogs.msdn.com/drnick/archive/2006/12/19/creating-faults-part-3.aspx

Description of how faults should work: http://blogs.msdn.com/drnick/archive/2006/12/19/creating-faults-part-3.aspx

我做错了什么还是这真的是 WCF 中的错误?

Am I doing something wrong or is this truly a bug in WCF?

推荐答案

这是我目前的解决方法:

This is my current workaround:

    /// <summary>
    /// Replacement for the static methods on FaultCode to generate Sender and Receiver fault codes due
    /// to what seems like bugs in the implementation for basicHttpBinding (SOAP 1.1). wsHttpBinding 
    /// (SOAP 1.2) seems to work just fine.
    /// 
    /// The subCode parameter for FaultCode.CreateReceiverFaultCode and FaultCode.CreateSenderFaultCode
    /// seem to take over the main 'faultcode' value in the SOAP 1.1 response, whereas in SOAP 1.2 the
    /// subCode is correctly put under the 'Code->SubCode->Value' value in the XML response.
    /// 
    /// This workaround is to create the FaultCode with Sender/Receiver (SOAP 1.2 terms, but gets
    /// translated by WCF depending on the binding) and an agnostic namespace found by using reflector
    /// on the FaultCode class. When that NS is passed in WCF seems to be able to generate the proper
    /// response with SOAP 1.1 (Client/Server) and SOAP 1.2 (Sender/Receiver) fault codes automatically.
    /// 
    /// This means that it is not possible to create a FaultCode that works in both bindings with
    /// subcodes.
    /// </summary>
    /// <remarks>
    /// See http://stackoverflow.com/questions/65008/net-wcf-faults-generating-incorrect-soap-11-faultcode-values
    /// for more details.
    /// </remarks>
    public static class FaultCodeFactory
    {
        private const string _ns = "http://schemas.microsoft.com/ws/2005/05/envelope/none";

        /// <summary>
        /// Creates a sender fault code.
        /// </summary>
        /// <returns>A FaultCode object.</returns>
        /// <remarks>Does not support subcodes due to a WCF bug.</remarks>
        public static FaultCode CreateSenderFaultCode()
        {
            return new FaultCode("Sender", _ns);
        }

        /// <summary>
        /// Creates a receiver fault code.
        /// </summary>
        /// <returns>A FaultCode object.</returns>
        /// <remarks>Does not support subcodes due to a WCF bug.</remarks>
        public static FaultCode CreateReceiverFaultCode()
        {
            return new FaultCode("Receiver", _ns);
        }
    }

遗憾的是,我没有看到一种在不破坏 SOAP 1.1 或 1.2 客户端的情况下使用子代码的方法.

Sadly I don't see a way to use subcodes without breaking either SOAP 1.1 or 1.2 clients.

如果您使用 Code.SubCode 语法,您可以创建与 SOAP 1.1 兼容的错误代码值,但它会破坏 SOAP 1.2.

If you use the Code.SubCode syntax, you can create SOAP 1.1 compatible faultcode values but it breaks SOAP 1.2.

如果您在 .NET 中使用正确的子代码支持(通过静态 FaultCode 方法或重载之一),它会破坏 SOAP 1.1,但可以在 SOAP 1.2 中工作.

If you use the proper subcode support in .NET (either via the static FaultCode methods or one of the overloads) it breaks SOAP 1.1 but works in SOAP 1.2.

这篇关于.NET WCF 错误生成不正确的 SOAP 1.1 错误代码值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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