zoukankan      html  css  js  c++  java
  • Retrieving HTTP content in .NET POSTing data

    POSTing data

    As I mentioned earlier POST data is important in Web request applications and getting the data into the proper format for posting can be tricky requiring possibly a fair amount of code. wwHttp abstracts the process with several overloads of the AddPostKey() method which handles the different POST modes: 1 – URLEncoded form variables, 2 – Multi-part form variables and files, 4 – XML or raw POST buffers.The base method looks as shown in Listing 3.

    Listing 3: wwHttp::AddPostKey handles POST data

    public void AddPostKey(string Key, byte[] Value)
    {
      if (this.oPostData == null)
      {
       this.oPostStream = new MemoryStream();
       this.oPostData = new BinaryWriter(this.oPostStream);
      }
     
      if (Key == "RESET")
      {
       this.oPostStream = new MemoryStream();
       this.oPostData = new BinaryWriter(this.oPostStream);
      }

      switch(this.nPostMode)
      {
       case 1:
         this.oPostData.Write(Encoding.GetEncoding(1252).GetBytes(
                Key + "=" +
                System.Web.HttpUtility.UrlEncode(Value) + "&"));
         break;
       case 2:
         this.oPostData.Write( Encoding.GetEncoding(1252).GetBytes(
          "--" + this.cMultiPartBoundary + "\r\n" +
          "Content-Disposition: form-data; name=\"" +Key+
          "\"\r\n\r\n") );
        
         this.oPostData.Write( Value );

         this.oPostData.Write( Encoding.GetEncoding(1252).GetBytes("\r\n") );
         break;
       default:
         this.oPostData.Write( Value );
         break;
      }
    }

    This method relies on a stream oPostStream to hold the cumulative POST data a user might send to the server. A BinaryWriter object is used to actually write to the stream sequentially without having to count bytes as you have to do with the raw stream.

    Next the actual POST data is actually written into the stream using the Write() of the BinaryWriter. Note that this version of AddPostKey() accepts a byte[] input parameter rather than a string so the data can be written in its raw format.

    The BinaryWriterWrite() method has overloads that allow for string parameters, however, this didn't work correctly for me as the encoding was screwed up in the output. Instead the code above explicitly performs the translation for any strings (including static strings like the ones for the multipart form vars) from string to byte array, using the proper encoding as discussed previously. Once again, this was tricky to figure out as you can set an encoding on the BinaryWriter, but which didn't appear to have any effect. The code shown above was the only working solution that runs correctly.

    There are several overloads to this method. Most importantly is a string version:

    public void AddPostKey(string Key, string Value)
    {
      this.AddPostKey(Key,Encoding.GetEncoding(1252).GetBytes(Value));
    }

    which does little more than converting the string into a byte array with the proper encoding. Another version accepts a single POST buffer, which is typically used for XML or binary content.

    public void AddPostKey(string FullPostBuffer)
    {
      this.oPostData.Write( Encoding.GetEncoding(1252).GetBytes(FullPostBuffer) );
    }

    This one writes directly to the binary writer.

    Finally there's an AddPostFile() method which allows you to POST a file to the server when running with multi-part forms (PostMode=2) to provide HTML file upload capabilities.

    Listing 3.1: HTTP file upload method for multi-part forms

    public bool AddPostFile(string Key,string FileName)
    {
      byte[] lcFile; 

      if (this.nPostMode != 2) {
        this.cErrorMsg = "File upload allowed only with Multi-part forms";
       this.bError = true;
        return false;
      }

      try
      {    
       FileStream loFile = new FileStream(FileName,System.IO.FileMode.Open,
                         System.IO.FileAccess.Read);

       lcFile = new byte[loFile.Length];
       loFile.Read(lcFile,0,(int) loFile.Length);
       loFile.Close();
      }
      catch(Exception e)
      {
       this.cErrorMsg = e.Message;
       this.bError = true;
       return false;
      }

      this.oPostData.Write( Encoding.GetEncoding(1252).GetBytes(
         "--" + this.cMultiPartBoundary + "\r\n" +
         "Content-Disposition: form-data; name=\"" + Key + "\" filename=\"" +
         new FileInfo(FileName).Name + "\"\r\n\r\n") );

      this.oPostData.Write( lcFile );

      this.oPostData.Write( Encoding.GetEncoding(1252).GetBytes("\r\n")) ;

      return true;
    }

    The AddPost style methods handle collecting POST data before the request is sent. The actual sending occurs in the main GetUrlStream() method of the wwHttp class.

    Listing 3.2: Sending the POST data to the server

    // *** Deal with the POST buffer if any
    if (this.oPostData != null)
    {
      Request.Method = "POST";
      switch (this.nPostMode)
      {
       case 1:
         Request.ContentType = "application/x-www-form-urlencoded";
         break;
       case 2:
         Request.ContentType = "multipart/form-data; boundary=" +
                    this.cMultiPartBoundary;
         this.oPostData.Write( Encoding.GetEncoding(1252).GetBytes( "--" +
                    this.cMultiPartBoundary + "\r\n" ) );
         break;
       case 4:
         Request.ContentType = "text/xml";
         break;
       default:
         goto case 1;
      }
     
      Stream loPostData = Request.GetRequestStream();

      //*** Copy the Memory Stream to the Request Stream
      this.oPostStream.WriteTo(loPostData);

      //*** Close the memory stream
      this.oPostStream.Close();
      this.oPostStream = null;

      //*** Close the Binary Writer
      this.oPostData.Close();
      this.oPostData = null;

      //*** Close Request Stream
      loPostData.Close();
    }

    This code finalizes the request for POST data by checking whether we've already written something into the POST buffer and if so configuring the POST request by specifying the content type. In the case of multi-part form POST an epilogue string is added to the end of the content.

    Writing out the data entails taking the data from the memory stream that holds our accumulated POST data and writing it out to the request stream (loPostData) which actually sends the POST data to the server.

    As you can see a lot of things are happening in order to properly POST data to the server and wwHttp takes care of the details for you with no additional code.

  • 相关阅读:
    C语言的swap函数的易错点
    C语言结构体指针,及其错误示范
    操作系统--问答题
    数据库-存储过程、触发器、视图-考研笔记
    数据库知识-恢复子系统、数据库恢复的基本技术、转储方法、日志文件、undo/redo操作、数据库镜像
    c语言,快排序找出第k小/大的数
    STM32的Flash读写保护,SWD引脚锁的各种解决办法汇总(2020-03-10)
    uCOS全家桶PDF文档整理汇总贴,提供论坛,百度云和腾讯云下载(2020-03-09)
    分享下之前做的STM32嵌入式Web完整设计教程和案例html,Ajax,Javacript,XML,cgi等
    【STM32H7教程】第71章 STM32H7的内部Flash应用之模拟EEPROM
  • 原文地址:https://www.cnblogs.com/goody9807/p/960012.html
Copyright © 2011-2022 走看看