Delphi調用 .net webService 返回數據;

最近在做此方面的工作,.net webService 返回的xml數據到了Delphi端就無法解析成數據源,通過將.net DataSet格式化爲Delphi可以解析的格式即可實現正常數據通信


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Collections;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Text;
using System.Xml;


namespace WDService
{
    // DotNetDataSetToClientDataSet
    public class DNDDSToCDS
    {
        public DNDDSToCDS()
        {
        }


        public static string Buf_BuieldDbsConnString(string ASQLServer, string ADtatBase, string ADbUser, string APassword)
        {
            string connstring = "server={0};uid=sa;pwd={1};database={2}";
            return String.Format(connstring, ASQLServer,APassword,ADtatBase);
        }
        /// <summary>
        /// dataset輸出成Delphi的Clientdataset的XML
        /// </summary>
        /// <param name="ds"></param>
        /// <param name="TableName"></param>
        /// <returns></returns>
        public static string ToClientDataSet(DataSet ds)
        {
            string TableName = "Table";
            int FieldCount = ds.Tables[TableName].Columns.Count;
            DataTable tempTable = ds.Tables[TableName];
            //StringBuilder result = new StringBuilder("<?xml version=\"1.0\" standalone=\"yes\"?>");
            StringBuilder result = new StringBuilder();
            result.Append("<DATAPACKET Version=\"2.0\">");
            result.Append("<METADATA><FIELDS>");
            for (int i = 0; i < FieldCount; i++)
            {
                DataColumn dc = tempTable.Columns[i];
                string FieldType = dc.DataType.Name.ToLower();
                CreateColumnSchema(ref result, dc, FieldType);
            }


            result.Append("</FIELDS><PARAMS/></METADATA>");
            result.Append("<ROWDATA>");
            int RowCount = tempTable.Rows.Count;
            for (int i = 0; i < RowCount; i++)
            {
                result.Append("<ROW ");
                for (int j = 0; j < FieldCount; j++)
                {
                    string value = "";
                    if (tempTable.Rows[i].RowState == DataRowState.Deleted)
                        break;


                    switch (tempTable.Columns[j].DataType.Name.ToLower())
                    {
                        case "byte[]":
                            if (!Convert.IsDBNull(tempTable.Rows[i][j]))
                                value = encodebase64byte((byte[])tempTable.Rows[i].ItemArray[j]);
                            break;
                        case "datetime":
                            if (!Convert.IsDBNull(tempTable.Rows[i][j]))
                            {
                                DateTimeConverter dtc = new DateTimeConverter();
                                DateTime datatime = (DateTime)dtc.ConvertFromString(tempTable.Rows[i][j].ToString());
                                value = datatime.ToString("yyyyMMddTHH:mm:ssfff");
                            }
                            break;
                        default:
                            if (!Convert.IsDBNull(tempTable.Rows[i][j]))
                            {
                                value = tempTable.Rows[i].ItemArray[j].ToString();
                                value = value.Replace(">", "&gt;");
                                value = value.Replace("\"", "&quot;");
                            }
                            break;
                    }
                    if (value.Length>0)
                        result.AppendFormat("{0}=\"{1}\" ", tempTable.Columns[j].ColumnName, value);
                }
                result.Append("/>");
            }
            result.Append("</ROWDATA></DATAPACKET>");
            return result.ToString();
        }


        public static bool ToDotNetDataSet(string ADataXml,ref DataSet NetDataSet)
        {
            Boolean retv = false;
            DataRow Row = null;
            int RowState = 0;
            string Change_Log = "";
            ArrayList RowStates = new ArrayList();
            DataTable TmpTable = NetDataSet.Tables[0];
            ArrayList ChgRows = new ArrayList();


            XmlTextReader reader = new XmlTextReader(ADataXml, XmlNodeType.Document, null);           
            reader.Read();            
            while (!reader.EOF)
            {
                if ((reader.NodeType == XmlNodeType.Element && reader.Name.ToUpper() == "PARAMS"))
                {
                    if (reader.HasAttributes)
                    {
                        if (reader.MoveToFirstAttribute())
                        {
                            do
                            {
                                if (reader.Name.Equals("Change_Log", StringComparison.OrdinalIgnoreCase))
                                {
                                    Change_Log = reader.Value;
                                    break;
                                }
                            }
                            while (reader.MoveToNextAttribute());
                        }
                    }
                }
                if ((reader.NodeType == XmlNodeType.Element && reader.Name.ToUpper() == "ROW"))
                {
                    if (reader.HasAttributes)
                    {
                        if (reader.MoveToFirstAttribute())
                        {
                            RowState = 0;
                            if (reader.Name.Equals("RowState", StringComparison.OrdinalIgnoreCase))
                            {
                                RowState = int.Parse(reader.Value);
                                reader.MoveToNextAttribute();
                            }


                            Row = TmpTable.NewRow();
                            do
                            {
                                DataColumn dc = TmpTable.Columns[reader.Name];
                                SetColumnValue(dc, ref Row, reader.Name, reader.Value);
                            }
                            while (reader.MoveToNextAttribute());
                            if (RowState < 3)
                                TmpTable.Rows.Add(Row);
                            else
                                ChgRows.Add(Row);
                            RowStates.Add(RowState);
                        }
                    }
                }
                reader.Read();
            }
            reader.Close();
            NetDataSet.Tables[0].AcceptChanges();


            if (Change_Log.Length > 0)
            {
                string[] Chglog = Change_Log.Split(' ');
                int OldCount = NetDataSet.Tables[0].Rows.Count;
                int ChgCount = Chglog.Length / 3;


                int OrgNo,EndNo, OprNo;
                for (int i = 0; i < ChgCount; i++)
                {
                    DataRow NewRow;
                    EndNo = int.Parse(Chglog[(i + 1) * 3 - 3]);
                    OprNo = int.Parse(Chglog[(i + 1) * 3 - 1]);
                    OrgNo = EndNo;
                    RowState = (int)RowStates[EndNo - 1];
                    if (RowState == 2 || RowState == 4 || RowState == 8 || RowState == 10 || RowState == 12)
                    {
                        switch (RowState)
                        {
                            case 2: //刪除行
                                NetDataSet.Tables[0].Rows[OrgNo - 1].Delete();
                                break;
                            case 4: //增加新行
                                NewRow = (DataRow)ChgRows[EndNo - OldCount - 1];
                                NetDataSet.Tables[0].Rows.Add(NewRow);
                                break;
                            case 8: //修改行
                                OrgNo = Buf_FindOrgNo(Chglog, i + 1, OldCount);
                                Row = NetDataSet.Tables[0].Rows[OrgNo - 1];
                                NewRow = (DataRow)ChgRows[EndNo - OldCount - 1];
                                for (int j = 0; j < TmpTable.Columns.Count; j++)
                                    if (!TmpTable.Columns[j].ReadOnly)
                                        Row[j] = NewRow[j];
                                break;
                            case 10: //修改行後刪除
                                OrgNo = Buf_FindOrgNo(Chglog, i + 1, OldCount);
                                NetDataSet.Tables[0].Rows[OrgNo - 1].Delete();
                                break;
                            case 12: ///增加行後修改
                                NewRow = (DataRow)ChgRows[EndNo - OldCount - 1];
                                NetDataSet.Tables[0].Rows.Add(NewRow);
                                break;
                        }
                    }
                }
                retv = true;
            }
            return retv;
        }


        private static int Buf_FindOrgNo(string[] AChglog, int ACurrNo,int AOldCount)
        {
            int NewNo, OldNo, OprNo;
            NewNo = int.Parse(AChglog[ACurrNo * 3 - 3]);
            OldNo = int.Parse(AChglog[ACurrNo * 3 - 2]);
            OprNo = int.Parse(AChglog[ACurrNo * 3 - 1]);
            if (OprNo == 2)
            {
                for (int i = ACurrNo - 1; i >= 0; i--)
                {
                    if (NewNo == int.Parse(AChglog[i * 3 - 3]))
                    {
                        ACurrNo = i;
                        break;
                    }
                }
                NewNo = int.Parse(AChglog[ACurrNo * 3 - 3]);
                OldNo = int.Parse(AChglog[ACurrNo * 3 - 2]);
                OprNo = int.Parse(AChglog[ACurrNo * 3 - 1]);
            }
            else if (OldNo > AOldCount)
            {
                for (int i = ACurrNo - 1; i >= 0; i--)
                {
                    if (OldNo == int.Parse(AChglog[i * 3 - 3]))
                    {
                        ACurrNo = i;
                        break;
                    }
                }
                NewNo = int.Parse(AChglog[ACurrNo * 3 - 3]);
                OldNo = int.Parse(AChglog[ACurrNo * 3 - 2]);
                OprNo = int.Parse(AChglog[ACurrNo * 3 - 1]);
            }
            if (OprNo == 8)
            {
                if (OldNo > AOldCount)
                    OldNo = Buf_FindOrgNo(AChglog, ACurrNo, AOldCount);
            }
            else
            {
                OprNo = 0;
            }
            return OldNo;
        }
        
        private static bool CreateColumnSchema(ref StringBuilder result, DataColumn dc, string FieldType)
        {
                //result.AppendFormat("<OldFIELD=\"{0}\" ", FieldType);
                //Boolean,Byte,Char,DateTime,Decimal,Double,Int16,Int32,Int64,SByte,Single,String,TimeSpan,UInt16,UInt32,UInt64,Byte[]
                switch (FieldType)
                {
                    case "boolean": //Bit
                        result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "boolean");
                        if (dc.ReadOnly)
                            result.Append(" readonly=\"true\"");
                        break;
                    case "byte": //Tinyint
                        result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "i2");
                        if (dc.ReadOnly)
                            result.Append(" readonly=\"true\"");
                        if (dc.AutoIncrement)
                            result.Append(" SUBTYPE=\"Autoinc\"");
                        break;
                    case "int16": //smallint
                        result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "i2");
                        if (dc.ReadOnly)
                            result.Append(" readonly=\"true\"");
                        if (dc.AutoIncrement)
                            result.Append(" SUBTYPE=\"Autoinc\"");
                        break;
                    case "int32": //int
                        result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "i4");
                        if (dc.ReadOnly)
                            result.Append(" readonly=\"true\"");
                        if (dc.AutoIncrement)
                            result.Append(" SUBTYPE=\"Autoinc\"");
                        break;
                    case "int64": //bigint
                        result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "i8");
                        if (dc.ReadOnly)
                            result.Append(" readonly=\"true\"");
                        if (dc.AutoIncrement)
                            result.Append(" SUBTYPE=\"Autoinc\"");
                        break;
                    case "datetime": //datetiem,smalldatetime
                        result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "dateTime");
                        if (dc.ReadOnly)
                            result.Append(" readonly=\"true\"");
                        break;
                    case "double": //float
                        result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "r8");
                        if (dc.ReadOnly)
                            result.Append(" readonly=\"true\"");
                        break;
                    case "single": //single
                        result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "r8");
                        if (dc.ReadOnly)
                            result.Append(" readonly=\"true\"");
                        break;
                    case "decimal": //money,smallmoney
                        result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\" DECIMALS=\"4\" WIDTH=\"19\"", dc.ColumnName, "fixed");
                        if (dc.ReadOnly)
                            result.Append(" readonly=\"true\"");
                        break;
                    case "guid": // uniqueidentifier
                        result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\" SUBTYPE=\"Guid\" WIDTH=\"38\"", dc.ColumnName, "string");
                        if (dc.ReadOnly)
                            result.Append(" readonly=\"true\"");
                        break;
                    case "string": //char(10),varchar(50),text
                        if (dc.MaxLength == -1)
                        {
                            result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "string");
                            result.AppendFormat(" WIDTH=\"{0}\"", "256");
                        }
                        else if (dc.MaxLength > 8000)
                        {
                            result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\" SUBTYPE=\"Text\"", dc.ColumnName, "bin.hex");
                        }
                        else
                        {
                            result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"", dc.ColumnName, "string");
                            result.AppendFormat(" WIDTH=\"{0}\"", dc.MaxLength);
                        }
                        if (dc.ReadOnly)
                            result.Append(" readonly=\"true\"");
                        break;
                    case "byte[]": //timestamp,image,varbinay(50),binay(50)
                        result.AppendFormat("<FIELD attrname=\"{0}\" fieldtype=\"{1}\"  SUBTYPE=\"Binary\"", dc.ColumnName, "bin.hex");
                        if (dc.ReadOnly)
                            result.Append(" readonly=\"true\"");
                        break;
                }
                result.Append("/>");
                return true;
        }


        private static bool SetColumnValue(DataColumn dc, ref DataRow Row, string fldname, string value)
        {
            switch (dc.DataType.Name.ToLower())
            {
                case "boolean": //Bit
                    //Row[fldname] = false;
                    if (value.Length > 0)
                        Row[fldname] = value.ToLower().Equals("true");
                    break;
                case "byte": //Tinyint
                    if (value.Length > 0)
                        Row[fldname] = byte.Parse(value);
                    break;
                case "int16": //smallint
                    if (value.Length > 0)
                        Row[fldname] = Int16.Parse(value);
                    break;
                case "int32": //int
                    if (value.Length > 0)
                        Row[fldname] = Int32.Parse(value);
                    break;
                case "int64": //bigint
                    if (value.Length > 0)
                        Row[fldname] = Int64.Parse(value);
                    break;
                case "datetime": //datetiem,smalldatetime
                    if (value.Length > 0)
                        if (value.Length > 10)
                            Row[fldname] = DateTime.ParseExact(value, "yyyyMMddTHH:mm:ssfff", System.Globalization.CultureInfo.CurrentCulture);
                        else
                            Row[fldname] = DateTime.ParseExact(value, "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture);
                    break;
                case "double": //float
                    if (value.Length > 0)
                        Row[fldname] = Double.Parse(value);
                    break;
                case "single": //single
                    if (value.Length > 0)
                        Row[fldname] = Single.Parse(value);
                    break;
                case "decimal": //money,smallmoney
                    if (value.Length > 0)
                        Row[fldname] = Decimal.Parse(value);
                    break;
                case "guid": // uniqueidentifier
                    if (value.Length > 0)
                        Row[fldname] = value;
                    break;
                case "string": //char(10),varchar(50),text
                    if (value.Length > 0)
                        if (value.Length > dc.MaxLength)
                            Row[fldname] = value.Substring(0, dc.MaxLength);
                        else
                            Row[fldname] = value;
                    break;
                case "byte[]": //timestamp,image,varbinay(50),binay(50)
                    if (value.Length > 0)
                        Row[fldname] = decodebase64("UTF-8", value);
                    break;
            }


            return true;
        }


        private static DataRow FindDataRowIndex(DataTable table, DataRow Row)
        {
            DataRow retv = null; 
            if (table.PrimaryKey.Length > 0)
            {
                object[] findTheseVals = new object[table.PrimaryKey.Length];
                for (int i = 0; i < table.PrimaryKey.Length; i++)
                    findTheseVals[i] = Row[table.PrimaryKey[0].ColumnName];
                retv = table.Rows.Find(findTheseVals);
            }
            else
            {
                StringBuilder expression = new StringBuilder();
                foreach (DataColumn dc in table.Columns)
                {
                    switch (dc.DataType.Name.ToLower())
                    {
                        case "boolean": //Bit
                            if (!Convert.IsDBNull(Row[dc.ColumnName]))
                                expression.Append(" and [" + dc.ColumnName + "]=" + Row[dc.ColumnName].ToString());
                            else
                                expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
                            break;
                        case "byte": //Tinyint
                            if (!Convert.IsDBNull(Row[dc.ColumnName]))
                                expression.Append(" and [" + dc.ColumnName + "]=" + Row[dc.ColumnName].ToString());
                            else
                                expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
                            break;
                        case "int16": //smallint
                            if (!Convert.IsDBNull(Row[dc.ColumnName]))
                                expression.Append(" and [" + dc.ColumnName + "]=" + Row[dc.ColumnName].ToString());
                            else
                                expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
                            break;
                        case "int32": //int
                            if (!Convert.IsDBNull(Row[dc.ColumnName]))
                                expression.Append(" and [" + dc.ColumnName + "]=" + Row[dc.ColumnName].ToString());
                            else
                                expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
                            break;
                        case "int64": //bigint
                            if (!Convert.IsDBNull(Row[dc.ColumnName]))
                                expression.Append(" and [" + dc.ColumnName + "]=" + Row[dc.ColumnName].ToString());
                            else
                                expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
                            break;
                        case "datetime": //datetiem,smalldatetime
                            if (!Convert.IsDBNull(Row[dc.ColumnName]))
                                expression.Append(" and [" + dc.ColumnName + "]='" + Row[dc.ColumnName].ToString() + "'");
                            else
                                expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
                            break;
                        case "double": //float
                            if (!Convert.IsDBNull(Row[dc.ColumnName]))
                                expression.Append(" and [" + dc.ColumnName + "]=" + Row[dc.ColumnName].ToString());
                            else
                                expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
                            break;
                        case "single": //single
                            if (!Convert.IsDBNull(Row[dc.ColumnName]))
                                expression.Append(" and [" + dc.ColumnName + "]=" + Row[dc.ColumnName].ToString());
                            else
                                expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
                            break;
                        case "decimal": //money,smallmoney
                            if (!Convert.IsDBNull(Row[dc.ColumnName]))
                                expression.Append(" and [" + dc.ColumnName + "]=" + Row[dc.ColumnName].ToString());
                            else
                                expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
                            break;
                        case "guid": // uniqueidentifier
                            if (!Convert.IsDBNull(Row[dc.ColumnName]))
                                expression.Append(" and [" + dc.ColumnName + "]='" + Row[dc.ColumnName].ToString() + "'");
                            else
                                expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
                            break;
                        case "string": //char(10),varchar(50),text
                            if (dc.MaxLength < 8000)
                                if (!Convert.IsDBNull(Row[dc.ColumnName]))
                                    expression.Append(" and [" + dc.ColumnName + "]='" + Row[dc.ColumnName].ToString()+"'");
                                else
                                    expression.Append(" and IsNull([" + dc.ColumnName + "],0)=0");
                            break;
                    }


                }
                DataRow[] trows = table.Select(expression.ToString().Substring(5));
                if (trows.Length > 0)
                    retv = trows[0];
            }


            return retv;
        }


        //編碼 
        public static string encodebase64byte(byte[] bytes)
        {
            try
            {
                return Convert.ToBase64String(bytes);
            }
            catch
            {
                return "";
            }
        }


        //解碼 
        public static byte[] decodebase64(string code_type, string code)
        {
            byte[] bytes = Convert.FromBase64String(code);
            return bytes;
        }


        //解碼 
        public static string decodebase64_str(string code_type, string code)
        {
            string decode = "";
            byte[] bytes = Convert.FromBase64String(code);
            try
            {
                decode = Encoding.GetEncoding(code_type).GetString(bytes);
            }
            catch
            {
                decode = code;
            }
            return decode;
        }


    }


    public class BuleSQLAccess
    {
        //與SQL Server的連接字符串設置
        private string _connString;
        private string _strSql;
        private string _ErrorText;
        private SqlCommandBuilder sqlCmdBuilder;
        private DataSet ds = new DataSet();
        private SqlDataAdapter da;


        private SqlConnection GetConn()
        {
            try
            {
                SqlConnection Connection =  new SqlConnection(this._connString);
                Connection.Open();
                return Connection;
            }
            catch (Exception ex)
            {
                _ErrorText = ex.Message;
                throw;
            }
        }


        public string ErrorText
        {
            get { return _ErrorText; }
        }


        //根據輸入的SQL語句檢索數據庫數據
        public DataSet Buf_GetDataSet(string connString, string strSql, string strTableName)
        {
            try
            {
                this._connString = connString;
                this._strSql = strSql;
                this.da = new SqlDataAdapter(this._strSql, this.GetConn());
                this.ds.Clear();
                this.da.FillSchema(ds, SchemaType.Mapped, strTableName);
                this.da.Fill(ds, strTableName);
                return ds;//返回填充了數據的DataSet,其中數據表以strTableName給出的字符串命名
            }
            catch (Exception ex)
            {
                _ErrorText = ex.Message;
                throw;
            }
        }


        //數據庫數據更新(傳DataSet和DataTable的對象)
        public DataSet Buf_PutDataSet(DataSet changedDs, string tableName)
        {
            try
            {
                this.da = new SqlDataAdapter(this._strSql, this.GetConn());
                this.sqlCmdBuilder = new SqlCommandBuilder(da);
                this.da.Update(changedDs, tableName);
                changedDs.AcceptChanges();
                return changedDs;//返回更新了的數據庫表
            }
            catch (Exception ex)
            {
                _ErrorText = ex.Message;
                throw;
            }
        }
    }


}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章