Я немного расстроен текущим проектом.У нас есть партнер по интеграции, который отказывается соответствовать контракту, и они ожидают контракт с ошибками с пользовательскими заголовками, а не контракт с сообщениями, определяемый WSDL, который включает те же заголовки и тело сообщения, действующее в соответствии с контрактом.Отправка ошибки SOAP с WCF не является проблемой, так как можно просто выбросить FaultException
.Настоящая привязка - это требование, чтобы ошибка содержала пользовательские заголовки.Мне удалось сериализовать пользовательский заголовок с помощью OperationContext
, однако он не сериализует способ, требуемый нашим партнером по интеграции.
Используя OperationContext.Current.OutgoingMessageHeaders
, можно создать пользовательский MessageHeader<T>
, содержащийобъект, который вы хотите включить в заголовок ... это может быть POCO, DataContract или MessageContract.При использовании контракта сообщений, пространства имен, кажется, игнорируются, и сериализованное сообщение имеет кучу недопустимых атрибутов xmlns = для каждого элемента сообщения, что также является проблемой.После создания MessageHeader вызов метода .GetUntypedHeader(name, namespace)
сгенерирует MessageHeader
, который может быть добавлен к OutgoingMessageHeaders OperationContext.Проблема в том, что вы не можете добавить объект непосредственно в заголовки ... они, очевидно, должны всегда быть обернутыми, поскольку метод 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
, имеет три дочерних элемента, мы, вероятно, были бы в бизнесе.Однако невозможно создать заголовок сообщения напрямую, охватывающий три отдельных объекта, и при использовании MessageContract с IsWrapped=false
каждый прямой дочерний элемент элемента imsx_syncResponseHeaderInfo
сериализуется с атрибутом xmlns
, который определяет неправильное пространство имен(похоже, что TNS принимает контракт на обслуживание).Это делает заголовок недействительным в соответствии с договорной схемой, и потребитель не может десериализовать его.
Есть ли способ добавить MessageContract к заголовкам исходящих сообщений сбоя SOAP, доставляемого WCF, не требуя егообернуты, и чтобы дочерние элементы не сериализовались каждый со своим собственным атрибутом xmlns, содержащим TNS контракта на обслуживание?