c# - уроки - wcf soap service




Как разобрать сообщение с мылом, загруженное из файла? (2)

Мне нужно разобрать сообщение SOAP, загружаемое с диска, в тип сгенерированного прокси. WCF делает это, когда получает сообщение от http-сервера, поэтому я должен быть в состоянии сделать это с диска.

Я использую webservice с WCF, я создал прокси-клиент из удаленного WSDL.

Вот структура XML, которую я получил из сети (она была зарегистрирована в System.ServiceModel.MessageLogging), которую я хочу проанализировать сгенерированным классом CRResponse .:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="urn:PourtuIntf" xmlns:ns2="ns2:PourtuIntf-IPourtu">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      <ns2:GetCRResponse>
         <return>
            <ResultCode>0</ResultCode>
            <CR>
               <Theme SOAP-ENC:arrayType="ns1:ItemType[5]">
                  <item>
                     <Key/>
                     <Section SOAP-ENC:arrayType="ns1:Section[3]">
...

Когда я вызываю операцию «GetCR» веб-службы, сообщение корректно преобразуется в созданный WCF-тип клиентского типа GetCRResponse, но я не знаю, как работает WCF, и мне нужно проанализировать файл с диска.

Я попытался разобрать сообщение таким образом:

  GetCRResponse body;
  using (var xmlReader =  XmlReader.Create("Requests\\CR.xml"))
  {
      Message m = Message.CreateMessage(xmlReader, int.MaxValue, MessageVersion.Soap11);
      body = m.GetBody<GetCRResponse>();
  }

В методе GeyBody это исключение возникает:

Expected element 'ActGetCRResponse' from namespace 'http://schemas.datacontract.org/2004/07/Pourtu.PourtuClient'.. Detecting 'Element' with name 'ActGetCRResponse', namespace 'urn:PourtuIntf-IPourtu' .

Я попытался использовать SoapFormatter:

using ( FileStream fs = new FileStream("Requests\\CR.xml", FileMode.Open) )
{
    SoapFormatter formatter = new SoapFormatter();
    body = (ActGetCRResponse)formatter.Deserialize(fs);
}

.. Deserialize выдает следующее исключение: Ошибка анализа, нет сборки, связанной с ключом xml 'ns2 GetCRResponse'.

Я не могу использовать сериализатор xml для десериализации для GetCRResponse с учетом атрибутов SOAP-ENC: arrayType, которые должны интерпретироваться сериализатором мыла.


Вы должны иметь возможность использовать XmlSerializer для выполнения этого с помощью SoapReflectionImporter .

var importer = new SoapReflectionImporter("ns2:PourtuIntf-IPourtu");
var mapping = importer.ImportTypeMapping(typeof(GetCRResponse));
var serializer = new XmlSerializer(mapping);
var response = serializer.Deserialize(reader) as GetCRResponse;

Класс SoapReflectionImporter предоставляет сопоставления типов для частей сообщения, закодированных в SOAP, как определено в документе описания веб-служб (WSDL). Он используется только тогда, когда веб-служба или клиент указывает кодировку SOAP, как описано в разделе 5 спецификации SOAP 1.1.

Следующая команда была использована для создания ваших клиентских контрактов из WSDL

SvcUtil.exe IPlotiservice.wsdl /t:code /serviceContract

Обновлено:

Message m = Message.CreateMessage(XmlReader.Create("C:\\testSvc\\login.xml"), int.MaxValue, MessageVersion.Soap11);
            SoapReflectionImporter importer = new SoapReflectionImporter(new SoapAttributeOverrides(), "urn:PlotiIntf-IPloti");
            XmlTypeMapping mapp = importer.ImportTypeMapping(typeof(ActGetCRResponse));
            XmlSerializer xmlSerializer = new XmlSerializer(mapp); 
            var o = (ActGetCRResponse)xmlSerializer.Deserialize(m.GetReaderAtBodyContents());

Справка





soap