Я пишу приложение на 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]);
Однако это приведет к тому, что имя элемента запроса будет изменено на имя действия SOAP по умолчанию (например, GetInformation), что снова вызовет ошибку. Я слишком долго боролся с этим, любые идеи будут оценены.
Кроме того, я создал тестовое приложение C #, которое использует службу и не имеет проблем при взаимодействии со службой.