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请求,看一下请求正文是什么内容
这个是一个附件上传的接口,包含了附件信息和一些参数信息,首先声明了请求类型是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


猜你喜欢
- 一、统一全站字符编码通过配置参数charset指明使用何种字符编码,以处理Html Form请求参数的中文问题package me.gacl
- 一、按钮组件1.1 提交按钮组件package swing;import java.awt.*;import java.awt.event.
- 本人一般也很少上传照片之类的女生喜欢玩的东西,但是偶尔还是要传一传的,为什么?因为现在与各种以前的朋友同学都很少联系,但是只要一发有个人照片
- 概述从今天开始, 小白我将带大家开启 Java 数据结构 & 算法的新篇章.KMP 算法KMP (Knuth-Morris-Prat
- 在本篇中我要介绍两个概念,我觉得这两个东西必须一起来介绍,这样才能连贯。C# 2.0里我们已经匿名方法了,现在类型也玩起匿名来了,怪不得大家
- Android 中下拉菜单,即如html中的<select>,关键在于调用setDropDownViewResource方法,以
- 会话会话:用户打开浏览器进行的一系列操作直至关闭浏览器的过程看作是一次会话HTTP协议是无状态的,不能实现跟踪对话。比如进入一个网站,每次操
- 方法1:C#Label1.Text = Request.Form["txtName"].ToString();vb.ne
- Dataway介绍Dataway 是基于 DataQL 服务聚合能力,为应用提供的一个接口配置工具。使得使用者无需开发任何代码就配置一个满足
- 本文实例讲述了Java网络编程实现的简单端口扫描器。分享给大家供大家参考,具体如下:在计算机网络的学习中,不由得觉得这门课的零碎知识点异常之
- Web基础和HTTP协议┌─────────┐┌─────────┐
- 前言内存管理的目的就是让我们在开发过程中有效避免我们的应用程序出现内存泄露的问题。内存泄露相信大家都不陌生,我们可以这样理解:「没有用的对象
- •强引用(FinalReference),在java中,有点像C++的指针,通过引用,可以对堆中的对象进行操作。强引用具备以下特点: 1.强
- //十进制转二进制 Console.WriteLine(Convert.ToString(69, 2)); //十进制转八进制 Consol
- 1.简介这是一个用于实现像微信朋友圈和微博的类似的九宫格图片展示控件,通过自定义viewgroup实现,使用方便。 多图根据屏幕适配,单张图
- 今天提交代码的时候突然发现IDEA的SVN面板Version Control下面多出来这么一句话:顿时心里咯噔一下,这肯定不是好事啊。果然,
- java连接zookeeper实现zookeeperJava服务端连接Zookeeper,进行节点信息的获取,管理…整理成一个基本工具添加依
- 1.创建线程 在Java中创建线程有两种方法:使用Thread类和使用Runnable接口。在使用Runnable接口时需要建立
- 对于之前最火的无外乎集五福了,而五福除了加十个好友获得外,最直接的途径就是支付宝的咻一咻了。那么咻一咻具体有哪些实现方式呢?下面我们将一一介
- JAVA 枚举单例模式及源码分析的实例详解 单例模式的实现有很多种,网上也分析了