我正在使用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#应用程序,并且在与服务通信时没有任何问题。
答案 0 :(得分:7)
我和其他在Delphi中遇到类似问题的人交谈过,似乎没有明确的方法可以解决这个问题。
相反,我使用的解决方案是将事件处理程序附加到发送SOAP消息的THTTPRIO对象的OnBeforeExecute事件,这使您可以作为字符串访问序列化的soap消息。从那里我刚解析出导致问题的属性,现在一切正常。
有点丑陋的解决方案,但它确实有效。