【问题标题】:WCF - Replacing Fault node of Fault SOAP message with a custom fault messageWCF - 用自定义故障消息替换故障 SOAP 消息的故障节点
【发布时间】:2014-05-29 16:18:23
【问题描述】:

我正在尝试使用 IErrorHandler 接口在 WCF 中实现自定义错误处理。我想将未处理的异常转换为自定义故障,这是我在 XSD 中获得的结构。

我的代码如下所示:

public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
    if (!(error is FaultException))
    {
        var customFault = new MyCustomFault
        {
            FaultString = "Something gone wrong",
            Detail = new DetailType
            {
                GeneralFault = new GeneralFaultType
                {
                    Errors = new[]
                    {
                        new ErrorType
                        {
                                Code = "333"
                        }
                    }
                }
            }
        };

        var faultException = new FaultException<MyCustomFault>(customFault);
        var msgFault = faultException.CreateMessageFault();
        fault = Message.CreateMessage(version, msgFault, faultException.Action);
    }
}

但是这段代码会产生输出soap消息

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <s:Fault>
         <faultcode>s:Client</faultcode>
         <faultstring xml:lang="cs-CZ">The creator of this fault did not specify a Reason.</faultstring>
         <detail>
... MyCustomFault goes here...
         </detail>
      </s:Fault>
   </s:Body>
</s:Envelope>

我只能影响故障的细节元素。我想实现,而不是 namespece "http://schemas.xmlsoap.org/soap/envelope/" 中的故障元素将是我的自定义故障对象。这甚至可能吗?我正在使用 XmlSerializer。

谢谢, 迈克尔

【问题讨论】:

    标签: .net wcf soap xmlserializer


    【解决方案1】:

    不,很遗憾,这是不可能的。 WCF 服务通过soap 错误消息通知客户端错误的唯一方法。因此WCF服务必须遵循soap规范。

    按照规范,所有故障消息必须具有相同的结构。请参阅规范:SOAP 1.2,查找第 5.4.6 节 SOAP 故障代码。您可以在那里找到示例(几乎与您提供的相同)以及所有节点的描述。

    在 SOAP 1.2 中引入了 Detail 节点(请参阅规范:Section 5.4.5 SOAP Detail Element)。

    提供您的错误合同,您可以在此处(在 Detail 元素内)以 xml 形式注入您的自定义错误。但其他xml结构是不变的。

    【讨论】:

      【解决方案2】:

      如果您需要遵循供应商的规范,您可以选择定义 xml 序列化,然后生成 xmlReader,然后将该阅读器传递到消息中。我做了类似的事情,所以我可以对一个行为/messageInspector 进行单元测试,以修复出现的错误。

      var xtr = new XmlTextReader("CustomSoapFault.xml");
      
      // I'm only allocating 1MB, you could allocate more if needed
      var message = Message.CreateMessage(xtr, 1024 * 1024, MessageVersion.Soap11);
      

      CustomSoapFault.xml的内容在哪里

      <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
         <s:Body>
            <s:Fault>
                ... CustomFault goes here...
            </s:Fault>
         </s:Body>
      </s:Envelope>
      

      当 .NET 使用它生成消息时,Message.IsFault 属性将返回 true。

      另外,请确保更新 soap 的命名空间和 MessageVersion 以使其匹配。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-21
        • 2013-08-14
        相关资源
        最近更新 更多