Delphi 2007 генерира неправилни SOAP съобщения

Пиша приложение в Delphi 2007, което използва уеб услуга. Използвах WSDL импортера, за да генерирам необходимия код за комуникация с услугата, но получавам грешки „неочакван поделемент (име на елемент)“, когато се опитвам да използвам услугата.

Използвайки Fiddler 2, открих, че проблемът е, че xmlns се добавя към масив от стойности, изпратени в SOAP съобщението:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="..." xmlns:xsd="..." xmlns:xsi="...">
<SOAP-ENV:Body>
  <Request xmlns="http://service.com/theService/">
    <UserName xmlns="">user</UserName>
    <Password xmlns="">pass</Password>
    <List xmlns="">
      <Item xmlns="http://service.com/theService/">123456</Item>
      <Item xmlns="http://service.com/theService/">84547</Item>
    </List>
  </Request>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Ако изпратя отново съобщението, създадено от Delphi във Fiddler, променяйки xmlns за елементи на Item на празен низ, вече не получавам грешка и услугата отговаря правилно. т.е.:

<List xmlns="">
  <Item xmlns="">123456</Item>
  <Item xmlns="">84547</Item>
</List>

Сега мога да се отърва от атрибута xmlns за елементи от списъка, като променя част от инициализацията на моя сервизен клас от:

InvRegistry.RegisterInvokeOptions(TypeInfo(ServicePort), ioDocument);
InvRegistry.RegisterInvokeOptions(TypeInfo(ServicePort), ioLiteral);
RemClassRegistry.RegisterSerializeOptions(RequestType, [xoLiteralParam]);

to:

InvRegistry.RegisterInvokeOptions(TypeInfo(ServicePort), ioDocument);
RemClassRegistry.RegisterSerializeOptions(RequestType, [xoHolderClass, xoLiteralParam]);

След това обаче това ще доведе до промяна на името на елемента Request на името на SOAP действието по подразбиране (напр. GetInformation), което отново ще доведе до грешка. Борих се с това твърде дълго, всякакви идеи ще бъдат оценени.

Освен това създадох тестово C# приложение, което използва услугата и няма никакви проблеми при комуникацията с услугата.


person Ryan S    schedule 19.01.2010    source източник


Отговори (1)


Говорих с други хора, които са имали подобни проблеми със сериализацията в Delphi, и изглежда, че няма ясен начин за отстраняване на този проблем.

Вместо това, решението, което избрах, е да прикача манипулатор на събитие към събитието OnBeforeExecute на обекта THTTPRIO, който изпраща SOAP съобщението, което ви дава достъп до сериализираното сапунено съобщение като низ. Оттам току-що анализирах атрибута, който причиняваше проблема, и сега всичко работи.

Малко грозно решение, но работи.

person Ryan S    schedule 23.01.2010
comment
Аз също в крайна сметка промених SOAP пакета, но в моя случай за върнат списък. - person mj2008; 25.01.2010