Как десериализовать сообщение WCF с помощью OperationContract - PullRequest
1 голос
/ 26 декабря 2010

Мне удалось создать клиент WCF, сгенерированный svcutil.exe из WSDL.Используя сгенерированный клиентский прокси-класс, я могу вызвать веб-сервис внешнего поставщика услуг.Я также преуспел в кодировании инспектора сообщений, так как мне нужно регистрировать как необработанный XML-запрос, так и ответ как полное сообщение SOAP в базу данных.

В случае возникновения чрезвычайной ситуации мне также нужно иметь возможность "импортировать" необработанныйXML ответ.Я обнаружил много подсказок об использовании XMLSerializer или десериализации сообщений WCF на основе контракта сообщений.

Но как я могу десериализовать необработанный ответ XML на основе контракта на операцию?Для первого теста я использую один из зарегистрированных необработанных ответов, сохраняю его в файл и теперь пытаюсь десериализовать его в тип ответа, сгенерированный в клиентском прокси.Каким-то образом я должен преуспеть в вызове DeserializeReply() из класса ClientOperation.Но как туда добраться?

Я с радостью принимаю любую помощь, так как я совсем новичок в WCF ... TIA, Stefan

Это то, что я попробовал после ответа Марка:

  public static RatingResult DeserializeResponseFromFile(string path)
  {
     var xmlReader = XmlReader.Create(path);
     var message = Message.CreateMessage(xmlReader, int.MaxValue, MessageVersion.Soap11);
     var readerAtBodyContents = message.GetReaderAtBodyContents();
     var dcs = new DataContractSerializer(typeof(RatingResult), "RatingResponse", "http://rating.webservice.xxx.de");

     // Error in line 6 position 7. 'EndElement' 'RatingResponse' from namespace
     // 'http://rating.webservice.xxx.de' is not expected.
     // Expecting element 'commonDataField'.
     var wsResult = (RatingResult)dcs.ReadObject(readerAtBodyContents);

     return wsResult;
  }

Это часть зарегистрированного файла ответов XML, который я пытаюсь десериализовать, чтобы набрать RatingResponse:

<soapenv:Envelope xmlns:soapenv="..." xmlns:soapenc="..." xmlns:xsd="..." xmlns:xsi="...">
  <soapenv:Header soapenv:encodingStyle="..." />
  <soapenv:Body soapenv:encodingStyle="...">
    <p933:RatingResponse xmlns:p933="http://rating.webservice.xxx.de">
      <RatingReturn href="#id0" />
    </p933:RatingResponse>
    <multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="..." xsi:type="p878:RatingResult" xmlns:p878="http://output.rating.webservice.xxx.de">
      <commonData href="#id1" />
      <acctData href="#id2" />
      <resultData href="#id3" />
    </multiRef>
    <multiRef id="id1" soapenc:root="0" soapenv:encodingStyle="..." xsi:type="p719:RatingCommonData" xmlns:p719="http://input.rating.webservice.xxx.de">
      <requestdate xsi:type="xsd:dateTime">2010-12-24T09:45:09.531Z</requestdate>
      ...

Я предполагаю, что у сериализатора контракта данных есть проблемы с десериализацией href.Обратите внимание, что сообщение, которое я пытаюсь десериализовать "вручную", было получено с помощью моего инспектора внедренных сообщений.При "нормальном" вызове веб-службы это сообщение без проблем десериализуется.

1 Ответ

3 голосов
/ 27 декабря 2010

Я не очень понимаю, что вы пытаетесь спросить и сделать .... на основании договора на операцию ?? контракт операции - это просто атрибут, который вы помещаете в вызов операции / метода, чтобы пометить его как метод службы .... контракт операции не делает ничего, даже удаленно связанного с сериализацией или десериализацией ..... Вы имеете в виду, как десериализовать сообщение XML, используя DataContractSerializer, который является сериализатором WCF по умолчанию ??затем попробуйте следующее: если у вас есть XML-ответ от вызова службы, который использовал WCF DataContractSerializer по умолчанию, вы должны иметь возможность десериализовать его следующим образом (при условии, что ваш сериализованный ответ XML содержится в переменной xmlResponse):1012 *

using(MemoryStream memStm = new MemoryStream())
using(StreamWriter stw = new StreamWriter(memStm))
{
   // write your response to the memory stream
   stw.Write(xmlResponse);
   stw.Flush();

   // "reset" memory stream
   memStm.Seek(0, SeekOrigin.Begin);

   // setup DataContractSerializer     
   DataContractSerializer dcs = new DataContractSerializer(typeof(YourDataType));

   // deserialize result XML into an instance of "YourDataType"
   var result = dcs.ReadObject(memStm);
}
...