将数据协定写入 SOAP 信封标头以处理传出的FaultException?

发布于 2024-11-16 21:17:22 字数 2269 浏览 2 评论 0原文

我对当前的项目感到有点困惑。我们有一个拒绝遵守合同的集成合作伙伴,他们期望一个带有自定义标头的错误合同,而不是包含相同标头和合同上有效的消息正文的 WSDL 定义的消息合同。使用 WCF 发送 SOAP 错误不是问题,因为可以简单地抛出 FaultException。真正的绑定是要求故障包含自定义标头。我能够使用 OperationContext 序列化自定义标头,但它没有按照我们的集成合作伙伴要求的方式序列化。

使用 OperationContext.Current.OutgoingMessageHeaders,可以创建一个自定义 MessageHeader,其中包含您希望包含在标头中的对象...它可以是POCO、DataContract 或 MessageContract。使用消息契约时,命名空间似乎会被忽略,并且序列化消息的每个成员上都有一堆无效的 xmlns= 属性,这也是一个问题。创建 MessageHeader 后,调用 .GetUntypedHeader(name, namespace) 方法将生成一个 MessageHeader,可以将其添加到 OperationContext 的 OutgoingMessageHeaders 中。问题是您无法直接将对象添加到标头...它们显然必须始终被包装,因为 GetUntypedHeader 方法需要包装器元素名称和命名空间。

所需的标头如下:

   <SOAP-ENV:Header>
      <imsx_syncResponseHeaderInfo xmlns="http://www.imsglobal.org/services/lti/xsd/CoreOutcomesService_bv1p0">
         <imsx_version>UNUSED</imsx_version>
         <imsx_messageIdentifier>12345678-abcd-1234-ef00-1234567890ab</imsx_messageIdentifier>
         <imsx_statusInfo>
            <imsx_codeMajor>failure</imsx_codeMajor>
            <imsx_severity>error</imsx_severity>
            <imsx_messageRefIdentifier>12345</imsx_messageRefIdentifier>
            <imsx_description>yadda yadda some error message here</imsx_description>
            <imsx_codeMinor>
               <imsx_codeMinorField>
                  <imsx_codeMinorFieldName>SomeCodeName</imsx_codeMinorFieldName>
                  <imsx_codeMinorFieldValue>somecode</imsx_codeMinorFieldValue>
               </imsx_codeMinorField>
            </imsx_codeMinor>
         </imsx_statusInfo>
      </imsx_syncResponseHeaderInfo>
   </SOAP-ENV:Header>

如果不是标头 imsx_syncResponsHeaderInfo 具有三个子元素,我们可能会正常工作。但是,不可能直接创建包装三个单独对象的消息标头,并且当使用带有 IsWrapped=false 的 MessageContract 时,imsx_syncResponseHeaderInfo 元素的每个直接子元素都会获取使用定义了不正确的命名空间的 xmlns 属性进行序列化(它似乎采用服务契约的 TNS)。根据合同模式,这使得标头无效,并且消费者无法反序列化它。

有没有某种方法可以将 MessageContract 添加到 WCF 传递的 SOAP 错误的传出消息标头中,而不需要对其进行包装,并且子元素不会使用自己的包含服务 TNS 的 xmlns 属性进行序列化合同?

I am in a bit of a pickle with a current project. We have an integration partner who is refusing to conform to contract, and they are expecting a fault contract with custom headers, rather than the WSDL-defined message contract that includes the same headers and a contractually valid message body. It is not a problem to send a SOAP fault with WCF, as one can simply throw FaultException. The real bind is the requirement that the fault contain custom headers. I was able to serialize a custom header by using the OperationContext, however it does not serialize the way our integration partner requires.

Using OperationContext.Current.OutgoingMessageHeaders, it is possible to create a custom MessageHeader<T> that contains the object you wish to include in the header...it can be a POCO, DataContract, or MessageContract. When using a message contract, namespaces seem to get ignored, and the serialized message has a bunch of invalid xmlns= attributes on each member of the message, which is also a problem. Once a MessageHeader is created, calling the .GetUntypedHeader(name, namespace) method will generate a MessageHeader that can be added to the OperationContext's OutgoingMessageHeaders. The problem is that you can't add an object to the headers directly...they apparently must always be wrapped, since the GetUntypedHeader method requires a wrapper element name and namespace.

The required header is as follows:

   <SOAP-ENV:Header>
      <imsx_syncResponseHeaderInfo xmlns="http://www.imsglobal.org/services/lti/xsd/CoreOutcomesService_bv1p0">
         <imsx_version>UNUSED</imsx_version>
         <imsx_messageIdentifier>12345678-abcd-1234-ef00-1234567890ab</imsx_messageIdentifier>
         <imsx_statusInfo>
            <imsx_codeMajor>failure</imsx_codeMajor>
            <imsx_severity>error</imsx_severity>
            <imsx_messageRefIdentifier>12345</imsx_messageRefIdentifier>
            <imsx_description>yadda yadda some error message here</imsx_description>
            <imsx_codeMinor>
               <imsx_codeMinorField>
                  <imsx_codeMinorFieldName>SomeCodeName</imsx_codeMinorFieldName>
                  <imsx_codeMinorFieldValue>somecode</imsx_codeMinorFieldValue>
               </imsx_codeMinorField>
            </imsx_codeMinor>
         </imsx_statusInfo>
      </imsx_syncResponseHeaderInfo>
   </SOAP-ENV:Header>

If it was not for the fact that the header, imsx_syncResponsHeaderInfo, has three child elements, we would probably be in business. However, it is impossible to create a message header directly that wraps three separate objects, and when using a MessageContract with IsWrapped=false, every direct child element of the imsx_syncResponseHeaderInfo element gets serialized with an xmlns attribute that defines an incorrect namespace (it seems to take the TNS of the service contract). That makes the header invalid according to the contractual schema, and the consumer cannot deserialize it.

Is there some way to add a MessageContract to the outgoing message headers of a WCF-delivered SOAP Fault, without requiring that it be wrapped, and such that the child elements to not get serialized each with their own xmlns attribute containing the TNS of the service contract?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

眸中客 2024-11-23 21:17:22

如上所述:

该问题实际上是由于业务合作伙伴反序列化我们的消息内容的方式造成的。他们当时不想对这个问题承担责任,这个负担就落在了我和我的团队身上。我们最终设法让他们解决了他们自己的问题,所以我们实际上不必解决问题。

As noted above:

The issue was actually due to how a business partner was deserializing our message contents. They did not want to take responsibility for the issue at the time, and the burden fell on my team and I. We finally managed to get them to fix their own issue, so we never actually had to solve the problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文