导航

[Delphi]在Delphi中使用由.NET开发的Web Service返回的DataSet类型

Posted on 2005-02-24 16:37  xujh  阅读(3762)  评论(8编辑  收藏  举报
在微软中国找到了一个官方的说法------不建议将DataSet直接作为返回值传送,因为里面含有大量复杂的schema以及更改等信息,大部分非.NET语言在解析上有困难。建议使用DataSet.WriteXML方法将简化后的XML版本作为一个WideString回传。经过试验,已经在Delphi下轻松通过,Delphi中还需要使用XML Mapper工具事先生成Transfomation(XTR)文件。

Delphi7客户端代码
----------------------------------------------------------------------------------------------------------------------------
unit WSTestMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, InvokeRegistry, StdCtrls, Rio, SOAPHTTPClient, Grids, DBGrids,
  DB, DBClient, DBTables, Provider, xmldom, Xmlxform,XMLIntf,XMLDoc,SOAPConst;

type
  TForm1 = class(TForm)
    HTTPRIO1: THTTPRIO;
    Button1: TButton;
    Memo1: TMemo;
    XMLTransformProvider1: TXMLTransformProvider;
    ClientDataSet1: TClientDataSet;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses WSTestDefine;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  A:Service1Soap;
  B:WideString;
  XMLDoc: IXMLDocument;
begin
  A := HTTPRIO1 as Service1Soap;
  B := A.GetPersonTable;
  Memo1.Lines.Add( B );
  ClientDataset1.Active := FALSE;
  XMLDoc := NewXMLDocument;
  XMLDoc.Encoding := SUTF8;
  XMLDoc.LoadFromXML(B);
  XMLTransformProvider1.TransformRead.SourceXmlDocument := XMLDoc.GetDOMDocument;
  ClientDataset1.Active := TRUE;
end;

end.

---------------------------------------------------------------------------------------
.NET WebService代码
---------------------------------------------------------------------------------------
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;
using System.Data.OracleClient;
using System.IO;
namespace WS0622
{
 /// <summary>
 /// Service1 的摘要说明。
 /// </summary>

 public class Service1 : System.Web.Services.WebService
 {
  public Service1()
  {
  //CODEGEN: 该调用是 ASP.NET Web 服务设计器所必需的
   InitializeComponent();
  }

  #region 组件设计器生成的代码
 
  //Web 服务设计器所必需的
  private IContainer components = null;
    
  /// <summary>
  /// 设计器支持所需的方法 - 不要使用代码编辑器修改
  /// 此方法的内容。
  /// </summary>

  private void InitializeComponent()
  {

  }

  /// <summary>
  /// 清理所有正在使用的资源。
  /// </summary>

  protected override void Dispose( bool disposing )
  {
   if(disposing && components != null)
   {
    components.Dispose();
   }
   base.Dispose(disposing);  
  }
 
  #endregion

  // WEB 服务示例
  // HelloWorld() 示例服务返回字符串 Hello World
  // 若要生成,请取消注释下列行,然后保存并生成项目
  // 若要测试此 Web 服务,请按 F5 键


  [Serializable]
   public class Person
  {
   public Person()
   {
   }

   public Person(string name,string gender)
   {
    this.Name=name;
    this.Gender=gender;
   }

   public string Name="";
   public string Gender="";
  }
  [WebMethod(CacheDuration=60)]
  public Person[] GetPersons()
  {
   Person Alice=new Person("Alice","Female");
   Person Bob=new Person("Bob","Male");
   Person Chris=new Person("Chris","Female");
   Person Dennis=new Person("Dennis","Male");

   return new Person[]{Alice,Bob,Chris,Dennis};
  }

  [WebMethod]
  public string GetPersonTable()
  {
   DataTable table=new DataTable("Person");  
   table.Columns.Add("Name");
   table.Columns.Add("Gender");
   table.Rows.Add(new string[2]{"Alice","Female"});
   table.Rows.Add(new string[2]{"Bob","Male"});
   table.Rows.Add(new string[2]{"Chris","Female"});
   table.Rows.Add(new string[2]{"Dennis","Male"});
   table.Rows.Add(new string[2]{"Eric","Male"});
 
   DataSet dataset=new DataSet("PersonTable");
   dataset.Tables.Add(table);
 
   System.Text.StringBuilder strbuilder=new System.Text.StringBuilder();
   StringWriter writer=new StringWriter(strbuilder);
   dataset.WriteXml(writer,System.Data.XmlWriteMode.IgnoreSchema);
   return strbuilder.ToString();
  }
 }
}