SOAP 应用程序中的查询参数数据类型更改为 WideString
我有一个简单的 SOAP 应用程序: 中间层:TSOAPDataModule,包括链接到 TADOQuery 的 TDatasetProvider。 TADOQuery定义了一些参数(不同的数据类型) 客户端:TClientDataSet 链接到 TSOAPConnection,提供程序设置为 MiddleTier 中的 DatasetProvider。
在设计时,我可以成功从服务器获取 ClientDataSet 的参数和字段。在运行时,我以编程方式设置 ClientDataSet 的参数并调用 Open。但我收到一个关于参数值不正确的 SQL 错误(来自 SQL Server,通过中间层中的 ADOQuery,通过 SOAP 传递到客户端)。经过详细调试,我发现参数从客户端正确传递到了 SOAP 服务器。 Provider.Params 正确列出了所有参数。不幸的是,在 ADOQuery 打开之前(在从 DataSetProvider 分配 ADOQuery.Parameters 之后),所有参数的 DataType 都发生了更改。即:原始 ADOQuery 参数数据类型为 ftDateTime,但从 DataSetProvider 分配后,它变为 ftWideString。
对于客户端中任何不为 null 的参数数据类型都会发生这种情况 - 所有这些都变成 ftWideString。
我发现此更改发生在 TParam.Assign 中,其中 TParameter(Destination).Value 在 TParameter(Destination).DataType 之前分配。分配值后,将自动根据值的 varType 猜测数据类型。由于值来自 OleVariant,因此它始终被视为字符串。
我尝试更改 TParam.Assign 过程 = 在值之前分配数据类型。但通过这种方式,我得到了值类型与数据类型不兼容的 ADO 错误。
我认为问题在于参数被编码到 SOAP XML 请求中的方式。它们的值只是“{value}”,没有任何类型信息。
我在谷歌上搜索了很多这个问题,但没有找到任何类似行为的注释。
我做错了什么吗,或者这是 Delphi 中 SOAP 的错误?
PS:我运行 Delphi 2009
编辑: 我刚刚找到一个示例 SOAP 请求,其参数按以下结构编组:
<NS1:V NS2:VarArrayType="8204">
<V xsi:type="xsd:string">param1</V>
<V xsi:type="xsd:string">Frank</V>
<V xsi:type="xsd:byte">1</V>
<V xsi:type="xsd:byte">1</V>
</NS1:V>
在我的情况下,它看起来是这样的:
<NS1:V NS2:VarArrayType="8204">
<V>param1</V>
<V>Frank</V>
<V>1</V>
<V>1</V>
</NS1:V>
我认为这是我的麻烦的根源,但不知道如何让我的客户端添加 xsi:type 属性到 SOAP 请求。
I have a simple SOAP apllication:
Middle Tier: TSOAPDataModule including TDatasetProvider linked to TADOQuery. TADOQuery has defined a few Parameters (different datatypes)
Client: TClientDataSet linked to TSOAPConnection and provider set to DatasetProvider in MiddleTier.
In design time i can succesfully Fetch Params and Fields for the ClientDataSet from Server. In runtime I programaticaly set parameters for the ClientDataSet and call Open. But I get an SQL error (comming from SQL Server, through ADOQuery in Middle Tier, passed by SOAP to the client) about incorrect values in parameters. After detail debugging I found that the parameters are correctly passed from client to the SOAP server. The Provider.Params lists all the parameters correctly. Unfortunatelly before the ADOQuery opens (after the ADOQuery.Parameters are assigned from the DataSetProvider) the DataType of all the parameters are changed. ie.: original ADOQuery Parameter DataType was ftDateTime but after assignment from DataSetProvider it becomes ftWideString.
This happens for any Parameter DataType that is not null from the Client - all of them become ftWideString.
I have found that this change happens in TParam.Assign where TParameter(Destination).Value is assigned before TParameter(Destination).DataType. After the Value is assigned the DataType is automatically guessed from the varType of the Value. As the Value comes from OleVariant it is always considered to be String.
I tried to alter the TParam.Assign procedure = Assign DataType before Value. But in this way I get ADO Error of Value type being incompatible with DataType.
I think that the problem is in the way tha parameters are being encoded into SOAP XML request. Their values are simply '{value}' without any type information.
I've googled a lot for this problem, but didn't find even a note of simmillar behaviour.
Do I do something wrong, or is this a bug in SOAP in Delphi?
PS: I run Delphi 2009
EDIT:
I just found a sample SOAP request that has the params marshaled in the following structure:
<NS1:V NS2:VarArrayType="8204">
<V xsi:type="xsd:string">param1</V>
<V xsi:type="xsd:string">Frank</V>
<V xsi:type="xsd:byte">1</V>
<V xsi:type="xsd:byte">1</V>
</NS1:V>
The same in my case looks this way:
<NS1:V NS2:VarArrayType="8204">
<V>param1</V>
<V>Frank</V>
<V>1</V>
<V>1</V>
</NS1:V>
I think this is the root of my troubles but do not know how to make my client to add xsi:type attribuge to the SOAP request.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我找到了。我已在 RegisterInvokeOptions 中使用 Include ioDocument 注册了 SOAPDataModule,
使得 xsi:type 属性不包含在 Variant 类型数据中。这使得将参数值解组为 olestring 类型。所以我的问题的解决方案是:
I found it. I have registered my SOAPDataModule with
Including ioDocument in RegisterInvokeOptions made the xsi:type attribute not to be included in Variant type data. This made unmarshaling the param values to olestring types. So the solution for my problem is: