WCF - Индивидуальный клиентский запрос / ответ XML - PullRequest
4 голосов
/ 25 февраля 2011

Я пытаюсь использовать предоставляемую поставщиком веб-службу AXIS с клиентом WCF. Ожидается, что служба будет иметь элемент запроса / ответа <TXLife> в качестве корневого элемента тела SOAP (элемент операции не содержит его). Я использую XmlSerializer, потому что в моем контракте с данными есть некоторые особенности схемы ACORD. Например, сервер хочет видеть следующее (... и да, "service" - это имя операции ...):

...<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><TXLife><TXLifeRequest xmlns="">...    

Мой клиент генерирует XML с операцией, сериализованной как элемент обертки, подобный этому:

...<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><service xmlns="urn:example.servicecontract"><TXLife><TXLifeRequest xmlns="">...

С тэгом «extra», указывающим операцию в запросе, сервис не может обработать запрос и ошибки. Если я удалю тег <service>, веб-служба успешно обработает запрос.

К сожалению, служба также отправляет ответ с развернутым тегом <TXLife> в качестве корневого элемента:

...<soapenv:Body><TXLife xmlns=""><TXLifeResponse>...

Мой десериализатор неправильно обрабатывает ответ, и я получаю null объект обратно. Я предполагаю, потому что мой клиент ожидает тег-обертку ответа операции сервиса и не получает его. Я не получаю особой помощи от отладчика на уровне десериализации.

Я думал о реализации IClientMessageFormatter или даже IClientMessageInspector для изменения запроса / ответа (например, удалите тег операции из сообщения запроса и добавьте тег ответа в сообщение ответа). Я знаю, что Formatter внедряется как OperationalBehavior, но я не уверен, куда MessageInspector помещается в стек. Может быть, я иду по этому пути неправильно ... Любое понимание или предложения будут оценены. Простите, это моя первая попытка использования услуг WCF, и я постепенно прощупываю свой путь. К сожалению, все об этом сервисе, кажется, "на заказ".

Мой сервисный контракт:

[XmlSerializerFormat]
[ServiceContract(Namespace="urn:example.servicecontract")]
public interface IPayoutServiceContract
{
    [OperationContract]
    TXLife service([MessageParameter(Name = "TXLife")]TXLife request);
}

Часть службы WSDL:

<wsdl:types><schema targetNamespace="urn:Tx103Service" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><import id="tx" namespace="http://ACORD.org/Standards/Life/2" schemaLocation="../acord/TXLife2.8.92.xsd" /></schema></wsdl:types><wsdl:message name="serviceRequest"><wsdl:part element="tx:TXLife" name="acordRequest" /></wsdl:message><wsdl:message name="serviceResponse"><wsdl:part element="tx:TXLife" name="acordResponse" /></wsdl:message><wsdl:portType name="LifeWebService"><wsdl:operation name="service"><wsdl:input message="impl:serviceRequest" name="serviceRequest" /><wsdl:output message="impl:serviceResponse" name="serviceResponse" /></wsdl:operation></wsdl:portType>

Обновление:

Сначала я попытался использовать декоратор MessageContract(isWrapped=false) в прокси-классе (интерфейс запрещает это). Это ничего не сделало. Я также попробовал ароматы BodyStyle = WebMessageBodyStyle.Bare, тоже ничего. Я предполагаю, что это связано с использованием XMLSerializer. Мне кажется, что нет простого способа «украсить» мой способ решения этой проблемы.

Кстати: мой сервисный контракт, контракт на передачу данных и прокси-клиент находятся в отдельных проектах в соответствии с этой рекомендацией, которая показалась мне твердой: сообщение в блоге Мигеля Кастро

Update2:

Я создал классы-оболочки запросов / ответов, украшенные тегами MessageContract / MessageBodyMember. Теперь XML генерируется как ожидалось. Все еще получаю нулевой объект в ответе ...

Update3:

«Пустые» объекты в моем ответе фактически присутствовали в ответе XML, но не были десериализованы, потому что сериализатор искал их как квалифицированные объекты. Я изменил их на неквалифицированные, и после этого мои объекты обнаружились очень хорошо.

1 Ответ

4 голосов
/ 25 февраля 2011

Вы пытались использовать MessageContract с IsWrapped = false вместо [MessageParameter]?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...