Пиша приложение в 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# приложение, което използва услугата и няма никакви проблеми при комуникацията с услугата.