Delphi調用.NET的WebService

it2025-10-07  5

問題的來源請參考gattaca的留言,雖然問題狠簡單,但是對於不熟悉ClientaDataSet的人來說,還是值得研究的。本例將實現一個基於.NET的WebService,並且使用Delphi調用,獲取數據。

首先開發一個WebService,我使用VS2008下C#語言進行開發,新建一個ASP.NET Web Service工程,代碼如下: [WebMethod]     public string GetData() {         string ConnStr = "Provider=SQLOLEDB.1;Password=\"\";Persist Security Info=True;User ID=sa;Initial Catalog=Northwind;Data Source=192.168.1.100";         OleDbConnection myConnection = new OleDbConnection(ConnStr);         string strSQL = "select * from Employees";         OleDbDataAdapter myAdapter = new OleDbDataAdapter(strSQL, myConnection);         DataSet ds = new DataSet();         myAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;         myAdapter.Fill(ds, "Employees");

        return CSDS2DDS.ToClientDataSet(ds, "Employees");     }

其中CSDS2DDS是CSharpDataSetToDelphiDataSet的縮寫,它包含一個靜態方法,用於將.NET的數據集轉換為ClientDataSet所使用的XML。這個類的代碼如下: public class CSDS2DDS { public CSDS2DDS() { }

    public static string ToClientDataSet(DataSet ds, string TableName) {         int FieldCount = ds.Tables[TableName].Columns.Count;         string result = "<?xml version=\"1.0\" standalone=\"yes\"?>";         result += "<DATAPACKET Version=\"2.0\">";         result += "<METADATA><FIELDS>";         for (int i = 0; i < FieldCount; i++) {             DataColumn dc = ds.Tables[TableName].Columns[i];             string FieldType = dc.DataType.Name.ToLower();             // integer             if (FieldType.ToLower() == "int32")                 FieldType = "i4";             // int64             if (FieldType.ToLower() == "int64")                 FieldType = "i8";             // float             if (FieldType.ToLower() == "single")                 FieldType = "r8";             // memo             if (FieldType.ToLower() == "string" && dc.MaxLength > 255)                 FieldType = "bin.hex";             // bytes             if (FieldType.ToLower() == "byte[]")                 FieldType = "bin.hex";             result += string.Format("<FIELD attrname=\"{0}\" fieldtype=\"{1}\" ", dc.ColumnName, FieldType);             if (FieldType == "bin.hex" && dc.DataType.Name.ToLower() == "string")                 result += "SUBTYPE=\"Text\" ";             else if (FieldType == "string")                 result += string.Format("WIDTH=\"{0}\" ", dc.MaxLength);             else if (FieldType == "sqldatetime")                 result += "SUBTYPE=\"Formatted\"";             else if (FieldType == "bin.hex" && dc.DataType.Name.ToLower() != "string" || dc.DataType.Name.ToLower() == "byte[]")                 result += "SUBTYPE=\"Binary\"";             result += "/>";         }         result += "</FIELDS><PARAMS/></METADATA>";         result += "<ROWDATA>";         int RowCount = ds.Tables[TableName].Rows.Count;         for (int i = 0; i < RowCount; i++) {             result += "<ROW RowState=\"4\" ";             for (int j = 0; j < FieldCount; j++) {                 DataTable dt = ds.Tables[TableName];                 string value = dt.Rows[i].ItemArray[j].ToString();                 value = value.Replace("\"", "&quot;");                 result += string.Format("{0}=\"{1}\" ",                     dt.Columns[j].ColumnName,                     value);             }             result += "/>";         }         result += "</ROWDATA></DATAPACKET>";         return result;     } } 這個類非常明確,就是用循環的方式讀出.NET數據集中的數據,並且拼裝成ClientDataSet使用的XML 做完這一步,就可以將WebService部署去IIS,然後用Delphi直接調用了,用WSDL Importer或RO引入WSDL,生成單元後就可以調用它。 procedure TForm1.FormCreate(Sender: TObject); var xml: string; begin xml := Service.GetServiceSoap.GetData; ClientDataSet1.XMLData := xml; ClientDataSet1.Open; end; 程序執行後即可看到,數據從.NET端傳遞到了Delphi端。 由於轉換的代碼直接讀取.NET的數據集,因此對delphi端沒有任何影響。 如果以後.NET的數據集發生了改變,也只需要在服務器上直接修改轉換代碼,.NET數據集的格式改變的可能性非常小。至少從.NET1.1開始,到現在的.NET3.5,它完全沒有改變過。 注意:部署WebService時請使用IIS6.0,盡量使用Windows2003,如果用XP,可能會產生不可預知的問題。

转载于:https://www.cnblogs.com/bennylam/archive/2009/11/19/1605791.html

最新回复(0)