C#通过HTTP操作数据的模块 [转]

// 本程序提供了一个通过HTTP来操作数据库的类,这样少了本地安装乱七八糟的数据库驱动程序及复杂的设置,
// Web 服务器可以是任意的类型的,可以为 ASP , ASP.NET JSP 或其他,本模块提供了服务器的ASP.NET 的
// 例子
// 南京千里独行原创 请引用时勿删除本行 2004-12-31
using System;
using System.Net ;
namespace myConnection
{
 /// 
 /// XMLHttp数据库连接操作事件处理委托
 /// 
 /// 数据库连接对象
 /// 数据库命令对象
 /// 总的数据字节数
 /// 已完成的数据字节数
 public delegate void XMLHttpDBExecutingHandler( XMLHttpConnection conn , XMLHttpCommand cmd , long ContentLength , long ContentCompleted );
 /// 
 /// XMLHttp类型的数据库数据读取对象
 /// 
 public class XMLHttpReader : System.Data.IDataReader
 {
  private string[] strHead = null;
  private System.Collections.ArrayList myRows = new System.Collections.ArrayList();
  private bool bolClosed = false;
  private int intRowIndex = 0 ;
  private const string c_NullFlag = "[NULL]" ;

  /// 
  /// 根据字段名称获得字段序号,比较不区分大小写
  /// 
  /// 字段名称
  /// 字段的从0开始的序号,若没找到则返回-1
  public int GetIndexByName( string strName )
  {
   if( strName == null ) return -1 ;
   strName = strName.ToUpper().Trim();
   for( int iCount = 0 ; iCount < strHead.Length ; iCount ++ )
    if( strName.Equals( strHead[iCount]))
     return iCount ;
   return -1 ;
  }
     
  /// 
  /// 从一个数据库读取对象加载对象数据
  /// 
  /// 数据库数据读取对象
  /// 加载的记录的行数
  public int FromReader(System.Data.IDataReader myReader)
  {
   if( myReader != null)
   {
    // 加载列头信息
    strHead = new string[ myReader.FieldCount ];
    for( int iCount = 0 ; iCount < myReader.FieldCount  ; iCount ++ )
     strHead[iCount] = myReader.GetName(iCount).ToLower().Trim();
    // 加载数据
    myRows.Clear();
    intRowIndex = -1 ;
    while( myReader.Read())
    {
     string[] strValues = new string[ myReader.FieldCount];
     myRows.Add( strValues );
     for( int iCount = 0 ; iCount < myReader.FieldCount ;iCount ++ )
     {
      if( myReader.IsDBNull( iCount ) == false)
      {
       if( myReader[iCount] is byte[])
       {
        strValues[iCount] = Convert.ToBase64String( (byte[])myReader[iCount]);
       }
       else
        strValues[iCount] = myReader[iCount].ToString();
      }
     }// for
    }// while
    return myRows.Count ;
   }// if
   return -1;
  }// FromReader
  /// 
  /// 保存对象数据到XML节点
  /// 
  /// 根XML节点
  /// 保存的记录个数
  public int ToXML( System.Xml.XmlElement RootElement )
  {
   System.Xml.XmlElement RowElement = null;
   System.Xml.XmlElement FieldElement = null;
   while( RootElement.FirstChild != null)
    RootElement.RemoveChild( RootElement.FirstChild);
   // 保存列数据
   if( strHead != null && strHead.Length > 0 )
   {
    for( int iCount = 0 ; iCount < strHead.Length ;iCount ++ )
    {
     RootElement.SetAttribute("f" + iCount.ToString() , strHead[iCount]);
    }
    RootElement.SetAttribute("fieldcount" , strHead.Length.ToString());
   }
   // 保存数据
   if( myRows != null && myRows.Count > 0 )
   {
    System.Xml.XmlDocument myDoc = RootElement.OwnerDocument ;
    for( int RowCount = 0 ; RowCount < myRows.Count ; RowCount ++ )
    {
     string[] strValue = ( string[] ) myRows[RowCount];
     RowElement = myDoc.CreateElement("r");
     RootElement.AppendChild( RowElement );
     for( int iCount = 0 ; iCount < strValue.Length ; iCount ++ )
     {
      FieldElement = myDoc.CreateElement("f" + iCount.ToString());
      RowElement.AppendChild( FieldElement );
      if( strValue[iCount] == null )
       FieldElement.InnerText = c_NullFlag ;
      else
       FieldElement.InnerText = strValue[iCount];
     }
    }// for
    return myRows.Count ;
   }
   return -1 ;
  }// ToXML 
  /// 
  /// 从XML元素加载对象数据
  /// 
  /// XML节点
  /// 加载的数据的行数
  public int FromXML( System.Xml.XmlElement RootElement )
  {
   System.Xml.XmlElement RowElement = null;
   strHead = null;
   myRows.Clear();
   intRowIndex = -1 ;
   if( RootElement == null ) return -1 ;
   // 获得列信息
   System.Collections.ArrayList myHeads = new System.Collections.ArrayList();
   for( int iCount = 0 ; iCount < 255 ; iCount ++ )
   {
    if( RootElement.HasAttribute( "f" + iCount.ToString()))
    {
     string strName =  RootElement.GetAttribute("f" + iCount.ToString());
     myHeads.Add( strName.ToLower().Trim());
    }
    else
     break;
   }
   //strHead = new string[ myHeads.Count ];
   strHead = ( string[]) myHeads.ToArray( typeof(string));
   // 获得数据
   foreach( System.Xml.XmlNode myNode in RootElement.ChildNodes )
   {
    if( myNode is System.Xml.XmlElement )
    {
     RowElement = ( System.Xml.XmlElement ) myNode ;
     // 获得数据
     string[] strValues = new string[ strHead.Length];
     myRows.Add( strValues );
     int iFieldCount = 0 ;
     foreach(System.Xml.XmlNode myFieldNode in RowElement.ChildNodes)
     {
      if( myFieldNode is System.Xml.XmlElement )
      {
       strValues[iFieldCount] = ( myFieldNode.InnerText == c_NullFlag ? null : myFieldNode.InnerText ) ;
       iFieldCount ++ ;
      }
     }// foreach
    }// if 
   }// foreach
   return myRows.Count ;
  }//  FromXML 
  #region IDataReader 成员
  /// 
  /// 未实现
  /// 
  public int RecordsAffected
  {
   get {return 0; }
  }
  /// 
  /// 已重载:关闭对象
  /// 
  public bool IsClosed
  {
   get{ return bolClosed ; }
  }
  /// 
  /// 未实现
  /// 
  /// 
  public bool NextResult()
  {
   if( myRows == null || (intRowIndex+1) >= myRows.Count )
    return false;
   else
    return true;
  }
  /// 
  /// 已重载:关闭对象
  /// 
  public void Close()
  {
   bolClosed = true;
   strHead = null;
   myRows = null;
  }
  /// 
  /// 移动当前记录到下一行
  /// 
  /// 
  public bool Read()
  {
   intRowIndex ++ ;
   if( intRowIndex >= myRows.Count )
    return false;
   else
    return true;
  }
  /// 
  /// 已重载:不支持
  /// 
  public int Depth
  {
   get{ return 0; }
  }
  /// 
  /// 已重载:不支持
  /// 
  /// 
  public System.Data.DataTable GetSchemaTable()
  {
   // TODO:  添加 XMLHttpReader.GetSchemaTable 实现
   return null;
  }
  #endregion
  #region IDisposable 成员
  public void Dispose()
  {
   // TODO:  添加 XMLHttpReader.Dispose 实现
  }
  #endregion
        
  #region IDataRecord 成员
  /// 
  /// 已重载:获得指定列号的整数型数据
  /// 
  /// 从0开始的列号
  /// 转换成功的整形数据
  public int GetInt32(int i)
  {
   return Convert.ToInt32( this.GetString(i));
  }
  /// 
  /// 获得指定列名的数据
  /// 
  public object this[string name]
  {
   get
   {
    return this.GetString( this.GetIndexByName( name));
   }
  }
  /// 
  /// 获得指定列号的数据
  /// 
  object System.Data.IDataRecord.this[int i]
  {
   get
   {
    return this.GetString(i);
   }
  }
  /// 
  /// 获得指定列号的数据
  /// 
  /// 从0开始的列号
  /// 获得的数据
  public object GetValue(int i)
  {
   return GetString(i);
  }
  /// 
  /// 判断指定列号的数据是否为空
  /// 
  /// 从0开始的列号
  /// 是否为空
  public bool IsDBNull(int i)
  {
   return  GetString(i) == null;
  }
  public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
  {
   byte[] bytData = Convert.FromBase64String( GetString(i));
   int iCount = 0 ;
   for( ; iCount < length && ( iCount + fieldOffset < bytData.Length ) ; iCount ++ )
    buffer[iCount + bufferoffset ] = bytData[ iCount + fieldOffset];
   return iCount ;
  }
  /// 
  /// 获得指定列的字节数据
  /// 
  /// 
  /// 
  public byte GetByte(int i)
  {
   return Convert.ToByte( GetString(i));
  }
  /// 
  /// 未实现
  /// 
  /// 
  /// 
  public Type GetFieldType(int i)
  {
   return null;
  }
  /// 
  /// 获得数值数据
  /// 
  /// 
  /// 
  public decimal GetDecimal(int i)
  {
   return Convert.ToDecimal( this.GetString( i));
  }
  /// 
  /// 未实现
  /// 
  /// 
  /// 
  public int GetValues(object[] values)
  {
   // TODO:  添加 XMLHttpReader.GetValues 实现
   return 0;
  }
  /// 
  /// 已重载:返回指定列的名称
  /// 
  /// 
  /// 
  public string GetName(int i)
  {
   if( i >= 0 && i < strHead.Length )
    return strHead[i];
   else
    return null;
  }
  /// 
  /// 已重载:返回列数
  /// 
  public int FieldCount
  {
   get
   {
    return strHead.Length ;
   }
  }
  /// 
  /// 获得长整形数据
  /// 
  /// 
  /// 
  public long GetInt64(int i)
  {
   return Convert.ToInt64( GetString(i));
  }
  /// 
  /// 获得双精度浮点数
  /// 
  /// 
  /// 
  public double GetDouble(int i)
  {
   return Convert.ToDouble( GetString(i));
  }
  /// 
  /// 获得布尔类型数据
  /// 
  /// 
  /// 
  public bool GetBoolean(int i)
  {
   return Convert.ToBoolean( GetString(i));
  }
  /// 
  /// 未实现
  /// 
  /// 
  /// 
  public Guid GetGuid(int i)
  {
   // TODO:  添加 XMLHttpReader.GetGuid 实现
   return new Guid ();
  }
  /// 
  /// 获得时间类型数据
  /// 
  /// 
  /// 
  public DateTime GetDateTime(int i)
  {
   return Convert.ToDateTime( GetString(i));
  }
  /// 
  /// 未实现
  /// 
  /// 
  /// 
  public int GetOrdinal(string name)
  {
   return 0;
  }
  /// 
  /// 未实现
  /// 
  /// 
  /// 
  public string GetDataTypeName(int i)
  {
   return null;
  }
  /// 
  /// 获得单精度浮点数
  /// 
  /// 
  /// 
  public float GetFloat(int i)
  {
   return Convert.ToSingle( GetString(i));
  }
  /// 
  /// 未实现
  /// 
  /// 
  /// 
  public System.Data.IDataReader GetData(int i)
  {
   return null;
  }
  /// 
  /// 未实现
  /// 
  /// 
  /// 
  /// 
  /// 
  /// 
  /// 
  public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
  {
   return 0;
  }
  /// 
  /// 获得字符串类型数据
  /// 
  /// 
  /// 
  public string GetString(int i)
  {
   if( intRowIndex >= 0 && intRowIndex < myRows.Count && i >= 0 && i < strHead.Length )
   {
    string[] strValues = ( string[] ) myRows[intRowIndex];
    return strValues[i];
   }
   else
    throw new System.IndexOutOfRangeException("记录表错误:行数或列数越界,Row:" + intRowIndex.ToString() + " Col:" + i.ToString() );
  }
  /// 
  /// 获得字符类型数据
  /// 
  /// 
  /// 
  public char GetChar(int i)
  {
   return Convert.ToChar( GetString(i));
  }
  /// 
  /// 获得短整型数据
  /// 
  /// 
  /// 
  public short GetInt16(int i)
  {
   return Convert.ToInt16( GetString(i));
  }
  #endregion
 }// class XMLHttpReader
 //*******************************************************************************************
 //*******************************************************************************************
 /// 
 /// XMLHttp数据库处理对象使用的参数集合
 /// 
 public class XMLHttpParameterCollection : System.Data.IDataParameterCollection
 {
  private System.Collections.ArrayList myParams = new System.Collections.ArrayList();
  #region IDataParameterCollection 成员
  /// 
  /// 返回指定名称的参数对象
  /// 
  public object this[string parameterName]
  {
   get
   {
    foreach( XMLHttpParameter myParam in myParams )
     if( myParam.ParameterName == parameterName )
      return myParam ;
    return null;
   }
   set
   {
    // TODO:  添加 XMLHttpParameterCollection.this setter 实现
   }
  }
  public void RemoveAt(string parameterName)
  {
   object obj = this[parameterName];
   if( obj != null)
    myParams.Remove( obj );
  }
  public bool Contains(string parameterName)
  {
   return ( this[parameterName] != null);
  }
  public int IndexOf(string parameterName)
  {
   foreach( XMLHttpParameter myParam in myParams )
    if( myParam.ParameterName == parameterName )
     return myParams.IndexOf( myParam ) ;
   return -1 ;
  }
  #endregion
  #region IList 成员
  public bool IsReadOnly
  {
   get
   {
    // TODO:  添加 XMLHttpParameterCollection.IsReadOnly getter 实现
    return false;
   }
  }
  object System.Collections.IList.this[int index]
  {
   get
   {
    return myParams[index];
   }
   set
   {
    myParams[index] = value;
   }
  }
  void System.Collections.IList.RemoveAt(int index)
  {
   myParams.RemoveAt( index );
  }
  public void Insert(int index, object obj)
  {
   myParams.Insert( index , obj );
   // TODO:  添加 XMLHttpParameterCollection.Insert 实现
  }
  int System.Collections.IList.IndexOf( object obj)
  {
   return myParams.IndexOf( obj );
  }
  public void Remove(object obj)
  {
   myParams.Remove( obj );
  }
  bool System.Collections.IList.Contains(object obj)
  {
   return myParams.Contains( obj );
  }
  public void Clear()
  {
   myParams.Clear();
  }
 
  public int Add(object obj)
  {
   myParams.Add( obj );
   return 0 ;
  }
  public bool IsFixedSize
  {
   get
   {
    // TODO:  添加 XMLHttpParameterCollection.IsFixedSize getter 实现
    return false;
   }
  }
  #endregion
  #region ICollection 成员
  public bool IsSynchronized
  {
   get
   {
    // TODO:  添加 XMLHttpParameterCollection.IsSynchronized getter 实现
    return false;
   }
  }
  public int Count
  {
   get
   {
    return myParams.Count ;
   }
  }
  public void CopyTo(Array array, int index)
  {
   // TODO:  添加 XMLHttpParameterCollection.CopyTo 实现
  }
  public object SyncRoot
  {
   get
   {
    // TODO:  添加 XMLHttpParameterCollection.SyncRoot getter 实现
    return null;
   }
  }
  #endregion
  #region IEnumerable 成员
  public System.Collections.IEnumerator GetEnumerator()
  {
   return myParams.GetEnumerator();
  }
  #endregion
 }
 //********************************************************************************
 //********************************************************************************
 /// 
 /// XMLHttp数据库连接对象使用的参数类型
 /// 
 public class XMLHttpParameter : System.Data.IDataParameter
 {
  private System.Data.ParameterDirection    intDirection        = System.Data.ParameterDirection.Input ;
  private System.Data.DataRowVersion        intSourceVersion    = System.Data.DataRowVersion.Default ;
  private System.Data.DbType                intDbType            = System.Data.DbType.String ;
        
  private object objValue            = null;
  private string strParameterName = null;
  private string strSourceColumn    = null;
        
  /// 
  /// 用指定字符串数据初始化对象
  /// 
  /// 
  public XMLHttpParameter( string strValue)
  {
   objValue = strValue ;
  }
  /// 
  /// 无参数的初始化对象
  /// 
  public XMLHttpParameter()
  {}
  #region IDataParameter 成员
  /// 
  /// 获取或设置一个值,该值指示参数是只可输入、只可输出、双向还是存储过程返回值参数。  
  /// 
  public System.Data.ParameterDirection Direction
  {
   get{ return intDirection ;}
   set{ intDirection = value;}
  }
  /// 
  /// 获取或设置参数的 System.Data.DbType
  /// 
  public System.Data.DbType DbType
  {
   get{ return intDbType ;}
   set{ intDbType = value ;}
  }
  /// 
  ///  获取或设置该参数的值
  /// 
  public object Value
  {
   get{ return objValue ;}
   set{ objValue = value;}
  }
  public bool IsNullable
  {
   get
   {
    return false;
   }
  }
  public System.Data.DataRowVersion SourceVersion
  {
   get{ return intSourceVersion ;}
   set{ intSourceVersion = value;}
  }
  /// 
  /// 参数名称
  /// 
  public string ParameterName
  {
   get{ return strParameterName ;}
   set{ strParameterName = value;}
  }
  /// 
  /// 参数栏目名称
  /// 
  public string SourceColumn
  {
   get{ return strSourceColumn ;}
   set{ strSourceColumn = value;}
  }
  #endregion
 }
 //*************************************************************************************
 //*************************************************************************************
 /// 
 /// 使用XMLHttp进行数据库访问的命令对象
 /// 
 public class XMLHttpCommand : System.Data.IDbCommand
 {
  private System.Data.CommandType intCommandType = System.Data.CommandType.Text ;
  private System.Data.CommandBehavior intCmdBehavior = System.Data.CommandBehavior.Default ;
  private System.Data.UpdateRowSource intUpdatedRowSource = System.Data.UpdateRowSource.Both ;
  private int            intCommandTimeout    = 0 ;
  private bool        bolCancel            = false;
  private string        strCommandText        = null;
  /// 
  /// 对象执行类型 0:查询数据库 1:更新数据库
  /// 
  private int            intExecuteType        = 0 ;
  private XMLHttpConnection myConnection    = null;
  private XMLHttpParameterCollection myParameters = new XMLHttpParameterCollection();
  private int            intExecuteState        = 0 ;
  private System.Xml.XmlDocument myXMLDoc = new System.Xml.XmlDocument();
  private const string c_NullFlag = "[NULL]" ;


  /// 
  /// 正在执行命令事件处理
  /// 
  public XMLHttpDBExecutingHandler ExecuteEvent = null;
  private string        strHttpMethod        = "POST";
  /// 
  /// 正在执行的状态 0:没有执行 1:正在发送数据 2:正在接受数据 3:正在解析数据
  /// 
  public int ExecuteState
  {
   get{ return intExecuteState ;}
  }
  /// 
  /// 向HTTP服务器提交数据的方法
  /// 
  public string HttpMethod
  {
   get{ return strHttpMethod ;}
   set{ strHttpMethod = value;}
  }
  /// 
  /// 保存对象数据到一个XML节点中
  /// 
  /// 
  /// 
  public bool FromXML(System.Xml.XmlElement myElement )
  {
   if( myElement != null)
   {
    intExecuteType = StringCommon.ToInt32Value( myElement.GetAttribute("type"),0);
    strCommandText = myElement.GetAttribute("text");
    myParameters.Clear();
    foreach( System.Xml.XmlNode myNode in myElement.ChildNodes)
    {
     if( myNode.Name == "param" )
     {
      System.Xml.XmlElement myPElement = myNode as System.Xml.XmlElement ;
      XMLHttpParameter myParam = new XMLHttpParameter();
      myParam.ParameterName = myPElement.GetAttribute("name");
      myParam.Value = myPElement.InnerText ;
      myParameters.Add( myParam );
     }
    }
   }
   return true;
  }
  /// 
  /// 从一个XML节点加载对象数据
  /// 
  /// 
  /// 
  public bool ToXML( System.Xml.XmlElement myElement )
  {
   if( myElement != null)
   {
    myElement.SetAttribute("text", strCommandText);
    myElement.SetAttribute("type", intExecuteType.ToString());
    foreach( XMLHttpParameter myParam in myParameters )
    {
     System.Xml.XmlElement myPElement = myElement.OwnerDocument.CreateElement("param");
     myElement.AppendChild( myPElement );
     myPElement.SetAttribute("name" , myParam.ParameterName );
     myPElement.InnerText =( myParam.Value == null ? c_NullFlag : myParam.Value.ToString());
    }
   }
   return true;
  }
        
  /// 
  /// 发送并接受二进制数据
  /// 
  /// 
  /// 
  internal byte[] SendByteData( byte[] bytSend)
  {
   // 发送数据
   System.Net.HttpWebRequest myReq = myConnection.CreateHttpRequest();
   System.IO.Stream myStream = myReq.GetRequestStream();
   int iCount = 0 ;
   bolCancel = false;
   intExecuteState = 1 ;
   while( iCount < bytSend.Length )
   {
    if( iCount + 1024 > bytSend.Length)
    {
     myStream.Write(bytSend, iCount , bytSend.Length - iCount );
     iCount = bytSend.Length ;
    }
    else
    {
     myStream.Write(bytSend , iCount , 1024);
     iCount += 1024;
    }
    if( ExecuteEvent != null)
    {
     ExecuteEvent( myConnection , this , bytSend.Length , iCount );
    }
    if( bolCancel )
    {
     myStream.Close();
     myReq.Abort();
     return null;
    }
   }
   myStream.Close();
   // 接受数据
   intExecuteState = 2 ;
   System.Net.HttpWebResponse myRes = null;
   myRes = (System.Net.HttpWebResponse) myReq.GetResponse();
   myStream = myRes.GetResponseStream();
   System.IO.MemoryStream myBuf = new System.IO.MemoryStream(1024);
   byte[] bytBuf = new byte[1024];
   while(true)
   {
    int iLen = myStream.Read(bytBuf,0,1024);
    if(iLen ==0)
     break;
    myBuf.Write(bytBuf,0,iLen);
    if( ExecuteEvent != null)
    {
     ExecuteEvent( myConnection , this , myRes.ContentLength , myBuf.Length );
    }
    if( bolCancel )
    {
     myStream.Close();
     myRes.Close();
     myReq.Abort();
     return null ;
    }
   }
   myStream.Close();
   myRes.Close();
   myReq.Abort();
   byte[] bytReturn = myBuf.ToArray();
   myBuf.Close();
   return bytReturn ;
  }

  /// 
  /// 执行命令
  /// 
  /// 
  private bool ExecuteCommand()
  {
   myXMLDoc.LoadXml("");
   this.ToXML( myXMLDoc.DocumentElement);
   string strSend = myXMLDoc.DocumentElement.OuterXml ;
   byte[] bytSend = myConnection.SendEncod.GetBytes( strSend );
   byte[] bytReturn = SendByteData(bytSend);
   if( bytReturn == null)
    return false;
   // 解析数据
   intExecuteState = 3 ;
   char[] chrReturn = myConnection.ReserveEncod.GetChars(bytReturn);
   string strReserve =new string(chrReturn);
   strReserve = strReserve.Trim();
   myXMLDoc.PreserveWhitespace = true;
   //try    {
   myXMLDoc.LoadXml( strReserve );
   //}catch( Exception ext){System.Console.WriteLine( ext.ToString());}
   intExecuteState = 0 ;
   if( myXMLDoc.DocumentElement.GetAttribute("error")=="1")
   {
    throw new System.Exception("远程WEB数据库操作错误\n" + myXMLDoc.DocumentElement.InnerText );
   }
   return true;
  }// ExecuteCommand
        
  public string ExecuteString()
  {
   if( this.ExecuteCommand())
    return myXMLDoc.DocumentElement.InnerText ;
   else
    return null;
  }
  #region IDbCommand 成员
  public void Cancel()
  {
   bolCancel = true;
  }
  public void Prepare()
  {
   // TODO:  添加 XMLHttpCommand.Prepare 实现
  }
  /// 
  /// 指示或指定如何解释 System.Data.IDbCommand.CommandText 属性。
  /// 
  public System.Data.CommandType CommandType
  {
   get{ return intCommandType ;}
   set{ intCommandType = value;}
  }
  public System.Data.IDataReader ExecuteReader(System.Data.CommandBehavior behavior)
  {
   intCmdBehavior = behavior ;
   intExecuteType = 0 ;
   if( this.ExecuteCommand())
   {
    XMLHttpReader myReader = new XMLHttpReader();
    myReader.FromXML( myXMLDoc.DocumentElement );
    return myReader;
   }
   return null;
  }
  System.Data.IDataReader System.Data.IDbCommand.ExecuteReader()
  {
   intExecuteType = 0 ;
   if( this.ExecuteCommand())
   {
    XMLHttpReader myReader = new XMLHttpReader();
    myReader.FromXML( myXMLDoc.DocumentElement );
    return myReader;
   }
   return null;
  }
  public object ExecuteScalar()
  {
   // TODO:  添加 XMLHttpCommand.ExecuteScalar 实现
   return null;
  }
  public int ExecuteNonQuery()
  {
   intExecuteType = 1 ;
   if( this.ExecuteCommand())
    return Convert.ToInt32( myXMLDoc.DocumentElement.InnerText );
   return -1;
  }
  /// 
  /// 执行命令的超时时间
  /// 
  public int CommandTimeout
  {
   get{ return intCommandTimeout ;}
   set{ intCommandTimeout = value;}
  }
  public System.Data.IDbDataParameter CreateParameter()
  {
   return (System.Data.IDbDataParameter) ( new XMLHttpParameter());
  }
  /// 
  /// 数据库连接对象
  /// 
  public System.Data.IDbConnection Connection
  {
   get{ return myConnection ;}
   set{ myConnection = (XMLHttpConnection)value;}
  }
  public System.Data.UpdateRowSource UpdatedRowSource
  {
   get{ return intUpdatedRowSource ;}
   set{ intUpdatedRowSource = value;}
  }
  public string CommandText
  {
   get{ return strCommandText ;}
   set{ strCommandText = value;}
  }
  public System.Data.IDataParameterCollection Parameters
  {
   get{ return myParameters ; }
  }
  /// 
  /// 未支持
  /// 
  public System.Data.IDbTransaction Transaction
  {
   get
   {
    // TODO:  添加 XMLHttpCommand.Transaction getter 实现
    return null;
   }
   set
   {
    // TODO:  添加 XMLHttpCommand.Transaction setter 实现
   }
  }
  #endregion
  #region IDisposable 成员
  public void Dispose()
  {
   // TODO:  添加 XMLHttpCommand.Dispose 实现
  }
  #endregion
 }
 /// 
 /// 通过HTTP使用XML来操作数据的数据库连接对象
 /// 
 public class XMLHttpConnection : System.Data.IDbConnection
 {
        
  private string strConnectionString = null;
  private System.Data.ConnectionState intState = System.Data.ConnectionState.Closed ;
  private string strDataBase = null;
  private int intConnectionTimeout = 0 ;
  private string strIECookies = null;

  /// 
  /// 初始化对象 
  /// 
  public XMLHttpConnection(  )
  {
  }
  /// 
  /// 初始化对象 
  /// 
  /// 
  public XMLHttpConnection( string strConn )
  {
   strConnectionString = strConn ;
  }
  /// 
  /// 发送数据使用的编码
  /// 
  public System.Text.Encoding SendEncod = System.Text.Encoding.UTF8 ;
  /// 
  /// 接受数据使用的编码
  /// 
  public System.Text.Encoding ReserveEncod = System.Text.Encoding.GetEncoding(936);
  private System.Net.Cookie mySessionCookie = null;

  /// 
  /// 正在执行命令事件处理
  /// 
  public XMLHttpDBExecutingHandler ExecuteEvent = null;
  private string        strHttpMethod        = "POST";
  /// 
  /// 设置,返回IE浏览器使用的COOKIE字符串 
  /// 
  public string IECookies
  {
   get{ return strIECookies ;}
   set{ strIECookies = value;}
  }

  /// 
  /// 向HTTP服务器提交数据的方法
  /// 
  public string HttpMethod
  {
   get{ return strHttpMethod ;}
   set{ strHttpMethod = value;}
  }
  /// 
  /// 创建一个HTTP服务器连接对象
  /// 
  /// 
  internal System.Net.HttpWebRequest CreateHttpRequest()
  {
   System.Net.HttpWebRequest myReq =(System.Net.HttpWebRequest) System.Net.WebRequest.Create(strConnectionString);
   // 添加用于标示用户的COOKIE对象
   if( mySessionCookie != null)
   {
    myReq.CookieContainer = new System.Net.CookieContainer();
    myReq.CookieContainer.Add( mySessionCookie );
   }
   myReq.ContentType = "application/x-www-form-urlencoded";
   myReq.Method = strHttpMethod ;
   return myReq ; 
  }
  #region IDbConnection 成员
  /// 
  /// 更换数据库
  /// 
  /// 
  public void ChangeDatabase(string databaseName)
  {
   strDataBase = databaseName ;
  }
  /// 
  /// 未支持
  /// 
  /// 
  /// 
  public System.Data.IDbTransaction BeginTransaction(System.Data.IsolationLevel il)
  {
   return null;
  }
  /// 
  /// 未支持
  /// 
  /// 
  System.Data.IDbTransaction System.Data.IDbConnection.BeginTransaction()
  {
   return null;
  }
  /// 
  /// 返回数据库连接状态
  /// 
  public System.Data.ConnectionState State
  {
   get{return intState ;}
  }
  /// 
  /// 数据库连接字符串
  /// 
  public string ConnectionString
  {
   get{ return strConnectionString ; }
   set{ strConnectionString = value ; intState = System.Data.ConnectionState.Closed ;}
  }
  /// 
  /// 创建一个数据库命令对象
  /// 
  /// 
  public System.Data.IDbCommand CreateCommand()
  {
   XMLHttpCommand NewCmd    = new XMLHttpCommand();
   NewCmd.Connection        = this ;
   NewCmd.ExecuteEvent        = this.ExecuteEvent ;
   NewCmd.HttpMethod        = this.HttpMethod ;
   return NewCmd ;
  }

  /// 
  /// 打开数据库连接,本函数用于测试服务器是否可用,并设置正确的输入输出编码格式
  /// 
  public void Open()
  {
   intState = System.Data.ConnectionState.Connecting ;
   //CustomBasic customBasicModule = new CustomBasic();
           
   // Unregister the standard Basic authentication module.
   AuthenticationManager.Unregister("Basic");
   // Register the custom Basic authentication module.
   //AuthenticationManager.Register(customBasicModule);

   // 试图获得服务的标志用户身份的COOKIE对象
   mySessionCookie = null;
   if( strIECookies != null && strIECookies.Length > 0 )
   {
    string[] strItems = StringCommon.AnalyseStringList( strIECookies , ';' , '=' , false);
    if( strItems != null)
    {
     string strName = null;
     string strValue = null;
     // 根据传入的IE的Cookie值来判断用于标志用户的Cookie值
     // 此处认为标志用户的COOKIE的名称中含有 SESSION 
     for(int iCount = 0 ; iCount < strItems.Length ; iCount +=2)
     {
      string strItemName = strItems[iCount].ToUpper();
      if( strItemName.IndexOf("SESSION") >= 0 )
      {
       strName  = strItems[iCount].Trim();
       strValue = strItems[iCount+1] ;
       break;
      }
     }
     if( strName != null)
     {
      // 向服务器发送请求,获得标示用户的Cookie对象
      System.Net.HttpWebRequest myReq = this.CreateHttpRequest();
      myReq.CookieContainer = new System.Net.CookieContainer();
      System.IO.Stream myStream = myReq.GetRequestStream();
      byte[] bytSend = System.Text.Encoding.ASCII.GetBytes("");
      myStream.Write( bytSend,0 , bytSend.Length );
      myStream.Close();
      System.Net.HttpWebResponse myRes = myReq.GetResponse() as System.Net.HttpWebResponse ;
      for(int iCount = 0 ;iCount < myRes.Cookies.Count ;iCount ++ )
      {
       if( myRes.Cookies[iCount].Name == strName )
       {
        mySessionCookie = myRes.Cookies[0];
        mySessionCookie.Value = strValue ;
        break;
       }
      }// for
     }// if
    }
   }
   // 测试数据库连接,自动判断数据的输入和输出编码格式
   System.Collections.ArrayList myEncods = new System.Collections.ArrayList();
   myEncods.Add( System.Text.Encoding.GetEncoding(936));
   myEncods.Add( System.Text.Encoding.UTF8 );
   myEncods.Add( System.Text.Encoding.Unicode );
   myEncods.Add( System.Text.Encoding.UTF7 );
   myEncods.Add( System.Text.Encoding.ASCII );
   const string c_TestCommand    = "[testconnection]";
   const string c_TestOKFlag    = "test_ok_中文测试";
   System.Xml.XmlDocument myXMLDoc = new System.Xml.XmlDocument();
   myXMLDoc.LoadXml("");
   myXMLDoc.DocumentElement.SetAttribute("text", c_TestCommand );
   myXMLDoc.DocumentElement.SetAttribute("data", c_TestOKFlag );
   string strSend = myXMLDoc.DocumentElement.OuterXml ;
   using(XMLHttpCommand myCmd = (XMLHttpCommand) this.CreateCommand())
   {
    for(int iCount1 = 0 ; iCount1 < myEncods.Count ; iCount1 ++ )
    {
     byte[] bytSend = ( myEncods[iCount1] as System.Text.Encoding ).GetBytes( strSend );
     byte[] bytReturn = myCmd.SendByteData( bytSend ); 
     for( int iCount2 = 0 ; iCount2 < myEncods.Count ; iCount2 ++ )
     {
      System.Text.Encoding myEncode = (System.Text.Encoding ) myEncods[iCount2];
      char[] chrReturn = myEncode.GetChars(bytReturn);
      string strReturn = new string( chrReturn );
      if( strReturn.IndexOf(c_TestOKFlag) >= 0 )
      {
       this.SendEncod = (System.Text.Encoding) myEncods[iCount1];
       this.ReserveEncod = ( System.Text.Encoding ) myEncods[iCount2];
       intState = System.Data.ConnectionState.Open ;
       return ;
      }
     }
    }
   }
   intState = System.Data.ConnectionState.Closed ;
  }// void Open()
        
  public void Close()
  {
   // TODO:  添加 XMLHttpConnection.Close 实现
  }
  public string Database
  {
   get
   {
    return strDataBase;
   }
  }
  public int ConnectionTimeout
  {
   get
   {
    return intConnectionTimeout ;
   }
  }
  #endregion
  #region IDisposable 成员
  public void Dispose()
  {
   // TODO:  添加 XMLHttpConnection.Dispose 实现
   AuthenticationManager.Unregister("Basic");
  }
  #endregion
 }
 //
 //    
 //    // The CustomBasic class creates a custom Basic authentication by implementing the
 //    // IAuthenticationModule interface. It performs the following
 //    // tasks:
 //    // 1) Defines and initializes the required properties.
 //    // 2) Implements the Authenticate method.
 //  
 //    internal class CustomBasic : IAuthenticationModule
 //    {
 //
 //        private string m_authenticationType ;
 //        private bool m_canPreAuthenticate ;
 //
 //        // The CustomBasic constructor initializes the properties of the customized 
 //        // authentication.
 //        public CustomBasic()
 //        {
 //            m_authenticationType = "Basic";
 //            m_canPreAuthenticate = false;
 //        }
 //
 //        // Define the authentication type. This type is then used to identify this
 //        // custom authentication module. The default is set to Basic.
 //        public string AuthenticationType
 //        {
 //            get
 //            {
 //                return m_authenticationType;
 //            }
 //        }
 //
 //        // Define the pre-authentication capabilities for the module. The default is set
 //        // to false.
 //        public bool CanPreAuthenticate
 //        {
 //            get
 //            {
 //                return m_canPreAuthenticate;
 //            }
 //        }
 //
 //        // The checkChallenge method checks whether the challenge sent by the HttpWebRequest 
 //        // contains the correct type (Basic) and the correct domain name. 
 //        // Note: The challenge is in the form BASIC REALM="DOMAINNAME"; 
 //        // the Internet Web site must reside on a server whose
 //        // domain name is equal to DOMAINNAME.
 //        public bool checkChallenge(string Challenge, string domain) 
 //        {
 //            bool challengePasses = false;
 //
 //            String tempChallenge = Challenge.ToUpper();
 //
 //            // Verify that this is a Basic authorization request and that the requested domain
 //            // is correct.
 //            // Note: When the domain is an empty string, the following code only checks 
 //            // whether the authorization type is Basic.
 //
 //            if (tempChallenge.IndexOf("BASIC") != -1)
 //                if (domain != String.Empty)
 //                    if (tempChallenge.IndexOf(domain.ToUpper()) != -1)
 //                        challengePasses = true;
 //                    else
 //                        // The domain is not allowed and the authorization type is Basic.
 //                        challengePasses = false;
 //                else
 //                    // The domain is a blank string and the authorization type is Basic.
 //                    challengePasses = true;
 //
 //            return challengePasses;
 //        }
 //
 //        // The PreAuthenticate method specifies whether the authentication implemented 
 //        // by this class allows pre-authentication. 
 //        // Even if you do not use it, this method must be implemented to obey to the rules 
 //        // of interface implementation.
 //        // In this case it always returns false. 
 //        public Authorization PreAuthenticate(WebRequest request, ICredentials credentials) 
 //        {                
 //            return null;
 //        }
 //
 //        // Authenticate is the core method for this custom authentication.
 //        // When an Internet resource requests authentication, the WebRequest.GetResponse 
 //        // method calls the AuthenticationManager.Authenticate method. This method, in 
 //        // turn, calls the Authenticate method on each of the registered authentication
 //        // modules, in the order in which they were registered. When the authentication is 
 //        // complete an Authorization object is returned to the WebRequest.
 //        public Authorization Authenticate(String challenge, WebRequest request, ICredentials credentials) 
 //        {
 //            System.Text.Encoding ASCII = System.Text.Encoding.ASCII ;        
 //
 //            // Get the username and password from the credentials
 //            NetworkCredential MyCreds = credentials.GetCredential(request.RequestUri, "Basic");        
 //
 //            if (PreAuthenticate(request, credentials) == null)
 //                Console.WriteLine("\n Pre-authentication is not allowed.");
 //            else
 //                Console.WriteLine("\n Pre-authentication is allowed.");
 //
 //            // Verify that the challenge satisfies the authorization requirements.
 //            bool challengeOk = checkChallenge(challenge, MyCreds.Domain);
 //
 //            if (!challengeOk)
 //                return null;
 //
 //            // Create the encrypted string according to the Basic authentication format as
 //            // follows:
 //            // a)Concatenate the username and password separated by colon;
 //            // b)Apply ASCII encoding to obtain a stream of bytes;
 //            // c)Apply Base64 encoding to this array of bytes to obtain the encoded 
 //            // authorization.
 //            string BasicEncrypt = MyCreds.UserName + ":" + MyCreds.Password;
 //
 //            string BasicToken = "Basic " + Convert.ToBase64String(ASCII.GetBytes(BasicEncrypt));
 //
 //            // Create an Authorization object using the encoded authorization above.
 //            Authorization resourceAuthorization = new Authorization(BasicToken);
 //
 //            // Get the Message property, which contains the authorization string that the 
 //            // client returns to the server when accessing protected resources.
 //            Console.WriteLine("\n Authorization Message:{0}",resourceAuthorization.Message);
 //
 //            // Get the Complete property, which is set to true when the authentication process 
 //            // between the client and the server is finished.
 //            Console.WriteLine("\n Authorization Complete:{0}",resourceAuthorization.Complete);
 //
 //            Console.WriteLine("\n Authorization ConnectionGroupId:{0}",resourceAuthorization.ConnectionGroupId);
 //
 //
 //            return resourceAuthorization;
 //        }
 //    }
 /// 
 /// XMLHttp数据库连接服务器端模块,在某个ASP.NET页面中使用该模块就可以向 XMLHttpConnection 提供数据了
 /// 
 public class XMLHttpServer 
 {
  private System.Data.IDbConnection myConnection ;
  /// 
  /// 数据库连接对象
  /// 
  public System.Data.IDbConnection Connection
  {
   get{ return myConnection ;}
   set{ myConnection = value;}
  }
  /// 
  /// 执行操作
  /// 
  /// 
  /// 
  public string Execute(System.Xml.XmlDocument InputXMLDoc )
  {
   const string c_TestCommand    = "[testconnection]";
   const string c_TestOKFlag    = "test_ok_中文测试";
   const string c_NullFlag        = "[NULL]";
   if( InputXMLDoc.DocumentElement.Name == "null")
    return "";
   System.Xml.XmlDocument myOutXML = new System.Xml.XmlDocument();
   myOutXML.PreserveWhitespace = true;
   myOutXML.LoadXml("");
   myOutXML.DocumentElement.SetAttribute("version","1.0");
   try
   {
    string strText = InputXMLDoc.DocumentElement.GetAttribute("text");
    string strType = InputXMLDoc.DocumentElement.GetAttribute("type");
    System.Console.WriteLine("收到命令" + InputXMLDoc.DocumentElement.OuterXml );
    if( strText == c_TestCommand )
    {
     if( InputXMLDoc.DocumentElement.GetAttribute("data") == c_TestOKFlag )
      return  c_TestOKFlag ;
     else
      return "错误的输入编码";
    }
    else
    {
     if( myConnection != null && myConnection.State == System.Data.ConnectionState.Open )
     {
      using(System.Data.IDbCommand myCmd = myConnection.CreateCommand())
      {
       // 设置查询命令对象
       myCmd.CommandText = strText ;
       foreach( System.Xml.XmlNode myNode in InputXMLDoc.DocumentElement.ChildNodes )
       {
        if( myNode.Name == "param" && myNode is System.Xml.XmlElement )
        {
         System.Data.IDbDataParameter NewParam = myCmd.CreateParameter();
         string strValue = myNode.InnerText ;
         if( strValue == c_NullFlag )
          NewParam.Value = "";
         else
          NewParam.Value = strValue;
         myCmd.Parameters.Add( NewParam );
        }
       }
       if( strType == "0")
       {
        // 查询数据库
        System.Data.IDataReader myReader = myCmd.ExecuteReader();
        System.Xml.XmlElement RecordElement = null;
        System.Xml.XmlElement FieldElement = null;
        // 添加字段信息
        for( int iCount = 0 ; iCount < myReader.FieldCount ; iCount ++ )
        {
         myOutXML.DocumentElement.SetAttribute("f" + iCount.ToString(), myReader.GetName(iCount).ToLower());
        }
        // 添加查询所得数据
        while( myReader.Read())
        {
         RecordElement = myOutXML.CreateElement("r");
         myOutXML.DocumentElement.AppendChild( RecordElement );
         for(int iCount = 0 ; iCount < myReader.FieldCount ; iCount ++ )
         {
          FieldElement = myOutXML.CreateElement("f" + iCount.ToString());
          RecordElement.AppendChild( FieldElement );
          FieldElement.InnerText = ( myReader.IsDBNull( iCount ) ? c_NullFlag : myReader[iCount].ToString());
         }
        }
        myReader.Close();
       }
       if( strType == "1")
       {
        // 更新数据库
        int intRowCount = myCmd.ExecuteNonQuery();
        myOutXML.DocumentElement.InnerText = intRowCount.ToString();
       }
      }// using
     }
    }
    return myOutXML.DocumentElement.OuterXml ;
   }// try
   catch( Exception ext)
   {
    return XMLHttpServer.CreateErrorMessage(ext);
   }
  }// Execute
  /// 
  /// 生成用于保存错误的字符串
  /// 
  /// 
  /// 
  public static string CreateErrorMessage(Exception ext)
  {
   System.Xml.XmlDocument myXMLDoc = new System.Xml.XmlDocument();
   myXMLDoc.LoadXml("");
   myXMLDoc.DocumentElement.SetAttribute("error","1");
   myXMLDoc.DocumentElement.InnerText = ext.ToString();
   return myXMLDoc.DocumentElement.OuterXml ;
  }// CreateErrorMessage
 }// class XMLHttpServer
 public class StringCommon
 {
  /// 
  /// 分析一个保存列表数据的字符串并将分析结果保存在一个字符串数组中
  /// 该字符串格式为 项目名 值分隔字符 项目值 项目分隔字符 项目名 值分隔字符 项目值 ...
  /// 例如 若值分隔字符为 ; 项目分隔字符为 = 则该输入字符串格式为 a=1;b=2;c=33
  /// 则本函数将生成一个字符串数组 {a,1,b,2,c,33},数组元素为偶数个
  /// 
  /// 保存列表数据的字符串
  /// 项目分隔字符串
  /// 值分隔字符串
  /// 分析的项目是否允许重名
  /// 返回的依次保存项目名称和项目值的字符串,元素个数必为偶数个,参数不正确则返回空引用
  public static string[] AnalyseStringList( string strList ,char ItemSplit ,char ValueSplit ,bool AllowSameName)
  {
   // 判断参数的正确性
   if( strList == null || strList.Length == 0 )
    return null;
   System.Collections.ArrayList myList = new System.Collections.ArrayList();
   string    strItem        = null;
   string    strName        = null;
   string    strValue    = null;
   int        index1        = 0 ;
   while( index1 < strList.Length )
   {
    int index2 = strList.IndexOf( ItemSplit , index1 );
    if( index2 < 0 )
     index2 = strList.Length ;
    if( index2 > index1 + 1 )
    {
     // 获得单个项目
     strItem = strList.Substring( index1  , index2 - index1 );
     // 获得西项目名和项目值
     int index3 = strItem.IndexOf( ValueSplit );
     if( index3 > 0 )
     {
      strName = strItem.Substring(0 , index3 );
      strValue = strItem.Substring(index3 + 1 );
     }
     else
     {
      strName = strItem ;
      strValue = "";
     }
     // 注册新的项目
     bool bolAdd = true;
     if( AllowSameName == false)
     {
      foreach( NameValueItem myItem in myList)
      {
       if( myItem.Name == strName )
       {
        bolAdd = false;
        break;
       }
      }
     }
     if( bolAdd)
     {
      NameValueItem NewItem    = new NameValueItem();
      NewItem.Name            = strName ;
      NewItem.Value            = strValue ;
      myList.Add( NewItem );
     }
    }
    index1 = index2 + 1 ;
   }
   // 输出结果
   string[] strReturn = new string[ myList.Count * 2] ;
   int iCount = 0 ;
   foreach(NameValueItem myItem in myList)
   {
    strReturn[iCount  ]    = myItem.Name ;
    strReturn[iCount+1] = myItem.Value ;
    iCount += 2 ;
   }
   return strReturn ;
  }// string[] AnalyseStringList
  /// 
  /// 内部使用的名称和值的项目对
  /// 
  private class NameValueItem
  {
   public string Name  ;
   public string Value ;
  }
  /// 
  /// 将一个字符串转换为整数
  /// 
  /// 字符串
  /// 默认值
  /// 转换结果
  public static int ToInt32Value(string strData , int DefaultValue)
  {
   try
   {
    if(strData == null || strData.Length == 0)
     return DefaultValue;
    return Convert.ToInt32( strData);
    //                char[] myChars = strData.ToCharArray();
    //                int iValue = 0 ;
    //                int iCount = 0 ;
    //                bool bolNegative = false ;
    //                foreach( char myChar in myChars)
    //                {
    //                    iValue = (int)myChar ;
    //                    if( iValue >= 48 && iValue <= 57)
    //                        iCount = iCount * 10 + iValue - 48 ;
    //                    else
    //                        break;
    //                }
    //                return iCount ;
   }
   catch
   {
    return DefaultValue;
   }
  }
 }
}
posted on 2005-08-05 15:41  wanna  阅读(485)  评论(0编辑  收藏  举报