你的位置:首页 > ASP.net教程

[ASP.net教程]C#中POST数据和接收的几种方式(抛砖引玉)


POST方式提交数据,一种众所周知的方式:

html页面中使用form表单提交,接收方式,使用Request.Form[""]或Request.QueryString[""]来获取。

 

这里介绍另外一种POST方式和接收方式,就是将整个数据作为加入到数据流中提交和接收

接收方式:

Stream s = System.Web.HttpContext.Current.Request.InputStream;byte[] b = new byte[s.Length];s.Read(b, 0, (int)s.Length);return Encoding.UTF8.GetString(b);

只需要从input Stream中读取byte数据,然后转为string,再解析即可。如果要回复响应消息只需要用:Response.Write()  输出即可(和普通的页面输出一样)。

 

主动POST发送方式:

      HttpWebRequest webrequest = (HttpWebRequest)HttpWebRequest.Create(url);      webrequest.Method = "post";      byte[] postdatabyte = Encoding.UTF8.GetBytes(postData);      webrequest.ContentLength = postdatabyte.Length;      Stream stream;      stream = webrequest.GetRequestStream();      stream.Write(postdatabyte, 0, postdatabyte.Length);      stream.Close();      using (var httpWebResponse = webrequest.GetResponse())      using (StreamReader responseStream = new StreamReader(httpWebResponse.GetResponseStream()))      {        String ret = responseStream.ReadToEnd();        T result = (ret);        return result;      }

使用HttpClient对象发送

 public static string  Poststring url, string = new StringContent(= new MediaTypeHeaderValue("application/json");      HttpClient httpClient = new HttpClient();            HttpResponseMessage response = httpClient.PostAsync(url, httpContent).Result;      if (response.IsSuccessStatusCode)      {        Task<string> t = response.Content.ReadAsStringAsync();        return t.Result;      }      return string.Empty;    }     

 

从代码中可以看出仅仅是将字符串转为byte[] 类型,并加入到请求流中,进行请求即可达到POST效果,该种POST方式与上边所提到的接收方式相互配合使用。

下面一种方式是以键值对的方式主动POST传输的。

 

     /// <summary>    /// 发起httpPost 请求,可以上传文件    /// </summary>    /// <param name="url">请求的地址</param>    /// <param name="files">文件</param>    /// <param name="input">表单数据</param>    /// <param name="endoding">编码</param>    /// <returns></returns>    public static string PostResponse(string url, UpLoadFile[] files, Dictionary<string, string> input, Encoding endoding)    {      string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);      request.ContentType = "multipart/form-data; boundary=" + boundary;      request.Method = "POST";      request.KeepAlive = true;      //request.Credentials = CredentialCache.DefaultCredentials;      request.Expect = "";      MemoryStream stream = new MemoryStream();      byte[] line = Encoding.ASCII.GetBytes("--" + boundary + "\r\n");      byte[] enterER = Encoding.ASCII.GetBytes("\r\n");      ////提交文件      if (files != null)      {        string fformat = "Content-Disposition:form-data; name=\"{0}\";filename=\"{1}\"\r\nContent-Type:{2}\r\n\r\n";        foreach (UpLoadFile file in files)        {          stream.Write(line, 0, line.Length);    //项目分隔符          string s = string.Format(fformat, file.Name, file.FileName, file.Content_Type);          byte[] data = Encoding.UTF8.GetBytes(s);          stream.Write(data, 0, data.Length);          stream.Write(file.Data, 0, file.Data.Length);          stream.Write(enterER, 0, enterER.Length); //添加\r\n        }      }      //提交文本字段      if (input != null)      {        string format = "--" + boundary + "\r\nContent-Disposition:form-data;name=\"{0}\"\r\n\r\n{1}\r\n";  //自带项目分隔符        foreach (string key in input.Keys)        {          string s = string.Format(format, key, input[key]);          byte[] data = Encoding.UTF8.GetBytes(s);          stream.Write(data, 0, data.Length);        }      }      byte[] foot_data = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");   //项目最后的分隔符字符串需要带上--       stream.Write(foot_data, 0, foot_data.Length);      request.ContentLength = stream.Length;      Stream requestStream = request.GetRequestStream(); //写入请求数据      stream.Position = 0L;      stream.CopyTo(requestStream); //      stream.Close();      requestStream.Close();      try      {        HttpWebResponse response;        try        {          response = (HttpWebResponse)request.GetResponse();          try          {            using (var responseStream = response.GetResponseStream())            using (var mstream = new MemoryStream())            {              responseStream.CopyTo(mstream);              string message = endoding.GetString(mstream.ToArray());              return message;            }          }          catch (Exception ex)          {            throw ex;          }        }        catch (WebException ex)        {          //response = (HttpWebResponse)ex.Response;          //if (response.StatusCode == HttpStatusCode.BadRequest)          //{          //  using (Stream data = response.GetResponseStream())          //  {          //    using (StreamReader reader = new StreamReader(data))          //    {          //      string text = reader.ReadToEnd();          //      Console.WriteLine(text);          //    }          //  }          //}          throw ex;        }      }      catch (Exception ex)      {        throw ex;      }    }

 

通过两种主动POST提交 的代码可以看出,其主要区别在于发送前的数据格式 ContentType 的值。

下面列举几种常用的ContentType 值,并简述他们的区别

Content-Type 被指定为 application/x-www-form-urlencoded 时候,传输的数据格式需要如  title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3 所示格式,才能正确解析

Content-Type 被指定为 multipart/form-data 时候,所需格式如下面代码块中所示

Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA------WebKitFormBoundaryrGKCBY7qhFd3TrwAContent-Disposition: form-data; name="text"title------WebKitFormBoundaryrGKCBY7qhFd3TrwAContent-Disposition: form-data; name="file"; filename="chrome.png"Content-Type: image/pngPNG ... content of chrome.png ...------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

Content-Type 也可以被指定为 application/json ,最终传输格式为 {"title":"test","sub":[1,2,3]}  至于如何接收本人未经尝试,但是可以肯定的讲使用文章开头所说的接收方式接收后转为string类型再

发序列化是可行的。

 

Content-Type指定为 text/

<?"1.0"?><methodCall>  <methodName>examples.getStateName</methodName>  <params>    <param>      <value><i4>41</i4></value>    </param>  </params></methodCall>


此种方式,本人亦未经尝试,接受方式可以参考上文中 application/json 的接收方式。

由于

      new //读取       doc.DocumentElement;      E= new E= root.SelectSingleNode("FromUserName").InnerText,        ToUserName = root.SelectSingleNode("ToUserName").InnerText,        CreateTime = root.SelectSingleNode("CreateTime").InnerText,        MsgType = root.SelectSingleNode("MsgType").InnerText,      };      if ("text")      {        = root.SelectSingleNode("Content").InnerText;      }      else if ("event")      {        = root.SelectSingleNode("Event").InnerText;      }      return 
    private class E/// <summary>      /// 本公众账号      /// </summary>      public string ToUserName { get; set; }      /// <summary>      /// 用户账号      /// </summary>      public string FromUserName { get; set; }      /// <summary>      /// 发送时间戳      /// </summary>      public string CreateTime { get; set; }      /// <summary>      /// 发送的文本内容      /// </summary>      public string Content { get; set; }      /// <summary>      /// 消息的类型      /// </summary>      public string MsgType { get; set; }      /// <summary>      /// 事件名称      /// </summary>      public string EventName { get; set; }    }

 

至此,相信一部分同学能有所得。由于本人水平一般,文中所述可能有纰漏之处,还请路过高手指出,同时也欢迎在评论区贴出更好的 发送和接受方式,供大家学习和交流。

本文有参考:https://imququ.com/post/four-ways-to-post-data-in-http.html  ,向原文作者致谢。