我有一个简单的SOAP apllication: 中间层:TSOAPDataModule包括链接到TADOQuery的TDatasetProvider。 TADOQuery定义了一些参数(不同的数据类型) 客户端:TClientDataSet链接到TSOAPConnection,提供程序设置为MiddleTier中的DatasetProvider。
在设计时,我可以成功地从Server获取ClientDataSet的参数和字段。在运行时,我programaticaly设置ClientDataSet的参数并调用Open。但我得到一个SQL错误(从SQL Server,通过中间层的ADOQuery,由SOAP传递给客户端)关于参数中的错误值。在详细调试之后,我发现参数正确地从客户端传递到SOAP服务器。 Provider.Params正确列出所有参数。不幸的是,在ADOQuery打开之前(在从DataSetProvider分配ADOQuery.Parameters之后),所有参数的DataType都会发生变化。 ie。:原始的ADOQuery参数DataType是ftDateTime,但是在从DataSetProvider赋值后,它变为ftWideString。
对于任何非客户端的参数DataType都会发生这种情况 - 所有这些都变为ftWideString。
我发现这种变化发生在TParam.Assign中,其中TParameter(Destination).Value是在TParameter(Destination).DataType之前分配的。分配Value后,将自动从Value的varType中猜出DataType。由于Value来自OleVariant,因此它始终被认为是String。
我尝试更改TParam.Assign过程=在Value之前分配DataType。但是这样我就得到了ADO Error of Value类型与DataType不兼容。
我认为问题在于参数被编码到SOAP XML请求中的方式。它们的值只是“{value}”而没有任何类型信息。
我已经搜索过很多关于这个问题的内容,但是没有发现任何相似的行为。
我做错了什么,或者这是Delphi中SOAP的错误?
PS:我运行Delphi 2009
修改 我刚刚找到了一个示例SOAP请求,该请求的params在以下结构中编组:
<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 attribuge添加到SOAP请求中。
答案 0 :(得分:1)
我找到了。我已经用
注册了我的SOAPDataModuleInvRegistry.RegisterInterface(TypeInfo(IMyIntf), MyNamespace, 'UTF-8');
InvRegistry.RegisterInvokeOptions(TypeInfo(IMyIntf), [ioDocument, ioHasNamespace, ioIsAppServerSOAP]);
在RegisterInvokeOptions中包含ioDocument使得xsi:type属性不包含在Variant类型数据中。这使得对olestring类型的param值进行解组。所以我的问题的解决方案是:
InvRegistry.RegisterInvokeOptions(TypeInfo(IMyIntf), [ioHasNamespace, ioIsAppServerSOAP]);