Delphi 2007 生成不正确的 SOAP 消息
我正在 Delphi 2007 中编写一个使用 Web 服务的应用程序。我使用 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 中创建的消息,请将 Item 元素的 xmlns 更改为空字符串,我不再收到错误,并且服务响应正常。即:
<List xmlns="">
<Item xmlns="">123456</Item>
<Item xmlns="">84547</Item>
</List>
现在,我可以通过将服务类的初始化部分从:更改
InvRegistry.RegisterInvokeOptions(TypeInfo(ServicePort), ioDocument);
InvRegistry.RegisterInvokeOptions(TypeInfo(ServicePort), ioLiteral);
RemClassRegistry.RegisterSerializeOptions(RequestType, [xoLiteralParam]);
为:来
InvRegistry.RegisterInvokeOptions(TypeInfo(ServicePort), ioDocument);
RemClassRegistry.RegisterSerializeOptions(RequestType, [xoHolderClass, xoLiteralParam]);
摆脱列表项的 xmlns 属性:但是,这将导致请求元素名称更改为默认名称SOAP 操作(例如 GetInformation),这将再次导致错误。我已经为此苦苦挣扎太久了,任何想法将不胜感激。
此外,我还创建了一个使用该服务的测试 C# 应用程序,并且与该服务通信时没有任何问题。
I am writing an application in Delphi 2007 which consumes a web service. I used the WSDL importer to generate the necessary code to communicate with the service, but I'm getting "unexpected subelement (elementname)" errors when trying to use the service.
Using Fiddler 2, I've found that the problem is that an xmlns is being added to an array of values sent in the SOAP message:
<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>
If I resend the message created by Delphi in Fiddler, changing the xmlns for Item elements to an empty string, I no longer get an error, and the service responds properly. ie:
<List xmlns="">
<Item xmlns="">123456</Item>
<Item xmlns="">84547</Item>
</List>
Now, I am able to get rid of the xmlns attribute for list items by changing part of the initialization of my service class from:
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]);
However, this will then cause the Request element name to be changed to the name of the default SOAP action (ex. GetInformation), which will again cause an error. I've been struggling with this for way too long, any ideas would be appreciated.
Also, I've created a test C# app which consumes the service, and it doesn't have any problems communicating with the service.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我和其他在 Delphi 中遇到类似序列化问题的人交谈过,似乎没有明确的方法来解决这个问题。
相反,我采用的解决方案是将一个事件处理程序附加到发送 SOAP 消息的 THTTPRIO 对象的 OnBeforeExecute 事件,这使您能够以字符串形式访问序列化的肥皂消息。从那里我刚刚解析出了导致问题的属性,现在一切正常了。
这是一个有点丑陋的解决方案,但它确实有效。
I've spoken with other people who have had similar problems with serialization in Delphi, and it seems that there is no clear-cut way to fix this issue.
Instead, the solution I've gone with is to attach an event handler to the OnBeforeExecute event of the THTTPRIO object that sends the SOAP message, which gives you access to the serialized soap message as a string. From there I just parsed out the attribute that was causing the problem, and now everything works.
A bit of an ugly solution, but it works.