Я пишу приложение в 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]);
до:
InvRegistry.RegisterInvokeOptions(TypeInfo(ServicePort), ioDocument);
RemClassRegistry.RegisterSerializeOptions(RequestType, [xoHolderClass, xoLiteralParam]);
Однако это приведет к тому, что имя элемента Request изменится на имя действия SOAP по умолчанию (например, GetInformation), что снова приведет к ошибке. Я слишком долго боролся с этим, любые идеи были бы оценены.
Кроме того, я создал тестовое приложение на C #, которое использует сервис, и у него нет проблем с подключением к сервису.