Delphi 2007生成错误的SOAP消息

时间:2010-01-19 19:11:30

标签: web-services delphi soap delphi-2007

我正在使用Delphi 2007编写一个使用Web服务的应用程序。我使用WSDL导入程序生成与服务通信所需的代码,但在尝试使用该服务时,我收到“意外的子元素(elementname)”错误。

使用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>

如果我重新发送由Fiddler中的Delphi创建的消息,将Item元素的xmlns更改为空字符串,我不再收到错误,并且服务正确响应。即:

<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#应用程序,并且在与服务通信时没有任何问题。

1 个答案:

答案 0 :(得分:7)

我和其他在Delphi中遇到类似问题的人交谈过,似乎没有明确的方法可以解决这个问题。

相反,我使用的解决方案是将事件处理程序附加到发送SOAP消息的THTTPRIO对象的OnBeforeExecute事件,这使您可以作为字符串访问序列化的soap消息。从那里我刚解析出导致问题的属性,现在一切正常。

有点丑陋的解决方案,但它确实有效。