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]);

Однако это приведет к тому, что имя элемента запроса будет изменено на имя действия 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