关于 soap / web server 服务返回数据类型的问题
在soap / web server的业务中  返回类型经常是数据集,我定义如下结构
在编译过程没有问题。Type
TSoapDataSet = Class( TRemotable  )
Private
FDataset : TDataSet;
FName : String;
published
Property Name : String Read FName Write FName;
Property Dataset : TDataSet Read FDataSet Write FDataSet;
end;
但是在在ie 地址
http://localhost:1024/PlatSoapSvr.PlatSoapServer/wsdl/ISoapServer
内容出现 ,说dataset 类型不识别。
在delphi 里导入也是如此。- <xs:complexType name="TSoapDataSet">
- <xs:sequence>
  <xs:element name="Name" type="xs:string" /> 
  <xs:element name="Dataset" type="xs:" /> 
  </xs:sequence>
  </xs:complexType>
  
请问各位老大该如何是好。我想是否可以使用xml传递数据集。该如何做。谢谢  

解决方案 »

  1.   

    补充 如果自定义类型中,如果是普通的类型,如string 等没有问题。
     但是使用dataset错了。
      

  2.   

    因为DataSet是不是SOAP支持的标准数据类型,你必须定义一对函数实现DataSet和XML之间互相转换,具体方法可以参考DELPHI的XSBuiltIns单元的源码。
      

  3.   

    我用的是TClientDataSet,如:
    ClientDataSet1.XMLData := soap返回的xml数据,
      

  4.   

    注意了:soap只能返回的类型有:integer,boolean,menu,string ;array(动态而不是静态);char;不全面,但肯定不会返回dataset,recordset,^,静态array,record,struct ,如果要返回这些数据集,必须自定义数据结构,并且还要注册。
    我现在就遇到了这个问题,虽然注册了,但在客户端还是不可识别,不知原因,
    请教大家了。
      

  5.   

    TDataset是一个对象,不能在TRemotable中定义对象公开属性,如果一定要定义,需要实现它的序列化方法。你的需求很简单,没必要这样做,你想做的无非是传递dataset中包含的数据,那么只要定义一个如下的类:
    TSoapDataSet = Class( TRemotable  )
    Private
    FXMLData : string;
    FName : String;
    published
    Property Name : String Read FName Write FName;
    Property XMLData : string Read FXMLData Write FXMLData;
    end;这里的XMLData就是一个字符串,用它来存放要返回的Dataset数据,而这个数据可以用ClientDataset进行包装,读取ClientDataset.XMLDataset来获得。这样就用最小的代价实现了数据远程传递。如果不像这么做的话,也可以用varByte VariantArray来进行数据包装和解包(实际上就是序列化/反序列化)。
      

  6.   

    回复人: Raptor(猛禽) ( ) 信誉:115  2003-08-26 11:17:00  得分:0 
     
     
      因为DataSet是不是SOAP支持的标准数据类型,你必须定义一对函数实现DataSet和XML之间互相转换,具体方法可以参考DELPHI的XSBuiltIns单元的源码。
      
     
    猛禽说的这个转换就是序列化
      

  7.   

    to  Miracle(秋水长天)     目前 ClientDataSet1.XMLData 的方法已经没有问题。但是这个最主要的问题是新添加一个类型后需要对新的类型引用。
       
      在后边我定义新的接口,然后对此接口做统一的数据类型定义。并在webserver 使用动态执行函数, @func:=Self.MethodAddress('abc');
     if Assigned(@func) then
       func(Self);
    其中abc 函数在服务器 开发,并使用统一接口。这样 客户段不需要每次引用服务。客户段只需要按 统一接口调用服务器的功能就可以拉。
    (现在我在服务器又加了执行脚本的功能)关于 这 现在碰到主要问题是统一的接口,我想其中关键问题就是  “对象的序列化”在java vc里 object这样的基类就把序列化功能实现。而delphi 中 在TRemotableXS 继承实现。目前对这块没有更好的办法。
    不知道各位老大有什么好的办法另外有人说我又跑到dcom里的圈子里去了。 
    有soap的简单和穿透力,又有com的统一规范。多好。
      

  8.   

    好像除了用TRemotableXS没有什么好办法SOAP虽然通用,但性能太差,不是必须,还是少用。
      

  9.   

    如果使用自己的序列化机制而不顾及SOAP标准兼容的话,可以考虑使用XML描述对象的RTTI信息,然后客户端重建对象。
    比如创建一个类,具备
    function toString(AObject: TObject): string;

    function fromString(const RTTIXML: string):TObject;
    两个方法,toString函数把对象的RTTI包装成XML,而FromString则反向还原,中间SOAP传递的仍然是XML字符串