Delphi 2007 生成不正确的 SOAP 消息

发布于 2024-08-18 14:08:21 字数 1562 浏览 8 评论 0原文

我正在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无敌元气妹 2024-08-25 14:08:21

我和其他在 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文