C#中后台post请求常用的两种方式总结

作者:摇光m 时间:2023-04-21 17:29:40 

最近对接接口的时候,需要根据对方的请求数据类型来进行传值,常用的就是application/x-www-form-urlencoded,ajax提交数据时也是使用的这种方式,但是没办法传递文件之类的信息,另一种就是mutipart/form-data,可以同时传递参数与文件或二进制流,这里主要使用的就是这两种方式

1.application/x-www-form-urlencoded

首先创建一个HttpWebRequest,并且声明请求方法和请求头

程序使用HTTP协议和服务器交互主要是进行数据的提交,通常数据的提交是通过 GET 和 POST 两种方式来完成,

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded;charset:utf-8";

然后,我们需要进行拼接参数,这种请求方式,提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。

大部分服务端语言都对这种方式有很好的支持,这里使用foreach进行循环拼接

StringBuilder paraStrBuilder = new StringBuilder();
               foreach (string key in postParameters.Keys)
               {
                   paraStrBuilder.AppendFormat("{0}={1}&", key, postParameters[key]);
               }
               string para = paraStrBuilder.ToString();
               if (para.EndsWith("&"))
                   para = para.Remove(para.Length - 1, 1);

接着,将参数转为ASCII码,并且将参数写入请求中

byte[] bt = Encoding.UTF8.GetBytes(para);
               string responseData = String.Empty;
               request.ContentLength = bt.Length;
               //GetRequestStream 输入流数据
               using (Stream reqStream = request.GetRequestStream())
               {
                   reqStream.Write(bt, 0, bt.Length);
                   reqStream.Close();
               }

后面就是发送请求,获取响应内容

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
               {
                   Stream stream = response.GetResponseStream();
                   using (StreamReader streamReader = new StreamReader(stream, Encoding.UTF8))
                   {
                       retString = streamReader.ReadToEnd().ToString();
                   }
               }

这样,一个完整的post请求就完成了,还是比较简单的

2.mutipart/form-data

这种方式就比较麻烦了,常用于表单提交文件数据并且包含参数的形式,我们可以先通过postman请求,看一下请求正文是什么内容

C#中后台post请求常用的两种方式总结

这个是一个附件上传的接口,包含了附件信息和一些参数信息,首先声明了请求类型是mutipart/form-data,后面跟了一个boundary,并且内容是随机的,紧接着又以一段随机字符串开始,声明了第一个参数名name=“file”,然后换了两行,跟了文件信息,又是以同样的一段的字符串进行分割,拼接下一段参数信息,这个地方多试几遍,并且看看他的结构就能很好的写代码了

我们这里演示两种方式,方便大家理解,一种是参数里不含任何文件信息,只有keyvalue,另一种是包含了文件信息且还有额外参数

首先是第一种,没有文件信息

还是先创建一个http并声明请求头

var webRequest = (HttpWebRequest)WebRequest.Create(strUrl);
               var boundary = "---------------" + DateTime.Now.Ticks.ToString("x");
               // 边界符
               var beginBoundary = Encoding.ASCII.GetBytes("--" + boundary + "\r\n");
               // 最后的结束符
               var endBoundary = Encoding.ASCII.GetBytes("--" + boundary + "--\r\n");
               memStream.Write(beginBoundary, 0, beginBoundary.Length);
               // 设置属性
               webRequest.Method = "POST";
               webRequest.Timeout = 10000;
               webRequest.ContentType = "multipart/form-data; boundary=" + boundary;

第二行创建一个boundary作为分割字符,然后在声明一个起始位置与结束位置,详见postm请求图中第5行和第30行,就是起始标识与结束标识,并创建一个MemoryStream,不断的写入

然后进行参数拼接,这里要注意上图里,每个参数的格式

foreach (string key in postParameters.Keys)
               {
                   var stringKeyHeader = "Content-Disposition: form-data; name=\"{0}\"" +                                       "\r\n\r\n{1}\r\n";
                   var header = string.Format(stringKeyHeader, key, postParameters[key]);
                   var headerbytes = Encoding.UTF8.GetBytes(header);
                   memStream.Write(headerbytes, 0, headerbytes.Length);
               }

每一个Content-Disposition: form-data; name=""后,进行了两次换行,才拼接了值,然后又进行了一次换行没有文件信息就不拼接间隔值,继续拼接下一个值,在所有的值拼接完成后,加上结束标识

memStream.Write(endBoundary, 0, endBoundary.Length);

然后将拼接完成的流,重新写入请求流中

webRequest.ContentLength = memStream.Length;
               var requestStream = webRequest.GetRequestStream();
               memStream.Position = 0;
               var tempBuffer = new byte[memStream.Length];
               memStream.Read(tempBuffer, 0, tempBuffer.Length);
               memStream.Close();
               requestStream.Write(tempBuffer, 0, tempBuffer.Length);
               requestStream.Close();

后面就是发送请求,拿回响应内容

using (HttpWebResponse res = (HttpWebResponse)webRequest.GetResponse())
               {
                   using (Stream resStream = res.GetResponseStream())
                   {
                       byte[] buffer = new byte[1024];
                       int read;
                       while ((read = resStream.Read(buffer, 0, buffer.Length)) > 0)
                       {
                           responseContent += Encoding.UTF8.GetString(buffer, 0, read);
                       }
                   }
                   res.Close();
               }
               return responseContent;

到此,不包含文件信息的请求就完成了

第二种,包含了文件信息,且也包含参数,本质上只是多了一步单独的拼接步骤,所以这步可以放在所有的参数拼接完成后,紧接着继续拼接文件信息参数,所以这一步的代码,应该放在foreach之后且在foreach里需要拼接间隔值,这里就只放这一块的代码了,注意,如果在foreach之后还要继续拼接参数,就不要加结束标识

const string filePartHeader =
                           "Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"\r\n" +
                           "Content-Type: application/octet-stream\r\n\r\n";

var header1 = string.Format(filePartHeader, postParameters["realName"]);
               var headerbytes1 = Encoding.UTF8.GetBytes(header1);
               memStream.Write(headerbytes1, 0, headerbytes1.Length);

memStream.Write(FileByte, 0, FileByte.Length);
               string end = "\r\n";
               headerbytes1 = Encoding.UTF8.GetBytes(end);
               memStream.Write(headerbytes1, 0, headerbytes1.Length);

memStream.Write(endBoundary, 0, endBoundary.Length);

先按照格式编写参数名Content-Disposition: form-data; name=""; filename="" Content-Type: ,然后连续换两行,写入文件流,在换行写入结束标识,后面步骤就一样,只要看懂了开始的那张图,剩下的都是按照格式去拼接写入就好

到此带文件信息的传参也完成了,接触的越多,能学习的就越多,会的越多,不会的就越多,还有其他的请求方式我这里就不在详细介绍了!

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。 

来源:https://blog.csdn.net/zwy0724/article/details/108071742

标签:C#,后台,post请求
0
投稿

猜你喜欢

  • SpringBoot登录验证码实现过程详解

    2023-04-26 12:24:05
  • Android 13新功能及适配工作详解

    2022-04-13 11:05:33
  • 深入了解Java虚拟机栈以及内存模型

    2022-02-17 13:37:50
  • java如何消除太多的if else判断示例代码

    2023-01-17 21:57:40
  • Android10 分区存储的适配规则

    2022-11-25 12:22:53
  • maven <repositories>标签和<pluginRepositories>标签的使用

    2022-09-26 01:06:33
  • java启动线程的3种方式对比分析

    2023-12-17 08:38:41
  • 在Unity中实现简单的伪时间同步

    2023-09-11 03:40:46
  • 浅谈Java字符串比较的三种方法

    2023-05-13 12:26:51
  • SpringMVC实现文件上传下载功能

    2023-09-05 19:49:39
  • Android绘图常用方法汇总

    2023-11-19 20:06:43
  • c#与WMI使用技巧集第1/2页

    2022-03-16 05:16:01
  • android自定义ProgressDialog加载效果

    2021-06-04 19:29:30
  • C#中Predicate<T>与Func<T, bool>泛型委托的用法实例

    2022-11-14 13:28:46
  • 一篇文章带你深入了解Java基础(2)

    2023-12-09 21:06:23
  • 在idea中显示springboot面板的方法

    2022-01-02 22:00:57
  • 关于WPF异步MVVM等待窗体的介绍

    2022-08-03 00:54:19
  • java仿QQ微信聊天室功能的实现

    2022-05-14 17:44:28
  • android图片处理之让图片变成圆形

    2021-08-01 00:29:53
  • Windows下Flutter+Idea环境搭建及配置

    2022-01-22 18:12:13
  • asp之家 软件编程 m.aspxhome.com