我对当前项目有些不满。我们有一个拒绝遵守合同的集成合作伙伴,他们期望与自定义标头的错误合同,而不是包含相同标头和合同有效消息体的WSDL定义的消息合同。使用WCF发送SOAP错误不是问题,因为可以简单地抛出FaultException
。真正的绑定是要求故障包含自定义标头。我能够使用OperationContext
序列化自定义标头,但它不会按照我们的集成合作伙伴要求的方式序列化。
使用OperationContext.Current.OutgoingMessageHeaders
,可以创建一个自定义MessageHeader<T>
,其中包含您希望包含在标题中的对象...它可以是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 Fault的传出消息头中,而不需要将其包装,并且不要使用包含TNS的xmlns属性对子元素进行序列化服务合同?
答案 0 :(得分:0)
如上所述:
问题实际上是由于业务合作伙伴如何反序列化我们的消息内容。他们当时不想对这个问题负责,负担落在我的团队和我身上。我们最终设法让他们解决自己的问题,所以我们实际上从来没有解决过这个问题。