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

目录
  • 1.application/x-www-form-urlencoded
  • 2.mutipart/form-data

最近对接接口的时候,需要根据对方的请求数据类型来进行传值,常用的就是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: ,然后连续换两行,写入文件流,在换行写入结束标识,后面步骤就一样,只要看懂了开始的那张图,剩下的都是按照格式去拼接写入就好

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

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

(0)

相关推荐

  • C#通过HttpWebRequest发送带有JSON Body的POST请求实现

    目录 起因 原来的处理方式 新的方式 起因 很多博客都有描述到这个问题,那么为什么我还要写一篇文章来说一下呢,因为其他的都似乎已经过时了,会导致其实body 并没有发送过去.至于为什么不使用其他的诸如 HttpClient 之类的,是由于业务需要. 原来的处理方式 通过 GetRequestStream 来获取请求流,后把需要发送的 Json 数据写入到流中 private T PostDataViaHttpWebRequest<T>(string baseUrl, IReadOnlyDict

  • C#发送Get、Post请求(带参数)

    目录 Get请求 Post请求 Get请求 1.简单发送Get请求 /// <summary> /// 指定Url地址使用Get 方式获取全部字符串 /// </summary> /// <param name="url">请求链接地址</param> /// <returns></returns> public static string Get(string url) { string result = &qu

  • C#调用HTTP POST请求上传图片的示例代码

    现在很多B/S系统的开发都是通过API方式来进行的,一般服务端会开放一个API接口,客户端调用API接口来实现图片或文件上传的功能. GET和POST是什么?HTTP协议中的两种发送请求的方法. HTTP是什么?HTTP是基于TCP/IP的关于数据如何在万维网中如何通信的协议. HTTP的底层是TCP/IP.所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接.GET和POST能做的事情是一样一样的.你要给GET加上request body,给POST带上url参

  • C#通过GET/POST方式发送Http请求

    目录 两者的区别: 参数 传输数据的大小 安全性 Get请求 Post请求 介绍http请求的两种方式,get和post方式.并用C#语言实现,如何请求url并获取返回的数据 两者的区别: 参数 Get请求把提交的数据进行简单编码,同时将url的一部分发送到服务器 比如url:Http://127.0.0.1/login.jsp?Name=zhangshi&Age=30&Submit=%cc%E+%BD%BB 所以get请求方式提交的数据存在一定的安全隐患,如果在使用对安全性要求教高的操作

  • C#使用GET、POST请求获取结果

    C#使用GET.POST请求获取结果,这里以一个简单的用户登陆为例. 1. 使用GET请求获取结果 1.1 创建LoginHandler.aspx处理页面 protected void Page_Load(object sender, EventArgs e) { string result = ""; string userName = Request.QueryString["UserName"]; string password = Request.Query

  • C#使用HttpPost请求调用WebService的方法

    之前调用 WebService 都是直接添加服务引用,然后调用 WebService 方法的,最近发现还可以使用 Http 请求调用 WebService.这里还想说一句,还是 web api 的调用简单. WebService 服务端代码: public class WebServiceDemo : System.Web.Services.WebService { [WebMethod] public string HelloWorld() { return "Hello World"

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

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

  • Spring MVC获取HTTP请求头的两种方式小结

    1 前言 请求是任何Web服务要关注的对象,而请求头也是其中非常重要的信息.本文将通过代码讲解如何在Spring MVC项目中获取请求头的内容.主要通过两种方式获取: (1)通过注解@RequestHeader获取,需要在Controller中显式获取: (2)通过RequestContextHolder获取,可以任何地方获取. 接下来通过代码讲解. 2 通过注解@RequestHeader获取 需要在Controller中显示使用@RequestHeader. 2.1 获取某个请求头 只获取其

  • golang post请求常用的几种方式小结

    post请求常用的几种方式,记录一下 func httpPost() { resp, err := http.Post("https://www.abcd123.top/api/v1/login", "application/x-www-form-urlencoded", strings.NewReader("username=test&password=ab123123")) if err != nil { fmt.Println(er

  • Docker中数据卷(volume)管理的两种方式

    上篇文章给大家介绍过 docker基础知识之挂载本地目录的方法 ,今天给大家介绍Docker中数据卷(volume)管理的两种方式,具体内容如下所示: 什么是数据卷 数据卷( volume ):volume是存在于一个或多个容器中的特定文件或文件夹,这个目录以独立于联合文件系统的形式在宿主机中存在,并为数据的共享与持久化提供便利. 为什么要用数据卷 Docker分层文件系统存在的问题: Docker的镜像是由一系列的只读层组合而来的,当启动一个容器时, Docker加载镜像的所有只读层,并在最上

  • C语言中计算二叉树的宽度的两种方式

    C语言中计算二叉树的宽度的两种方式 二叉树作为一种很特殊的数据结构,功能上有很大的作用!今天就来看看怎么计算一个二叉树的最大的宽度吧. 采用递归方式 下面是代码内容: int GetMaxWidth(BinaryTree pointer){ int width[10];//加入这棵树的最大高度不超过10 int maxWidth=0; int floor=1; if(pointer){ if(floor==1){//如果访问的是根节点的话,第一层节点++; width[floor]++; flo

  • 详解python中字典的循环遍历的两种方式

    开发中经常会用到对于字典.列表等数据的循环遍历,但是python中对于字典的遍历对于很多初学者来讲非常陌生,今天就来讲一下python中字典的循环遍历的两种方式. 注意: python2和python3中,下面两种方法都是通用的. 1. 只对键的遍历 一个简单的for语句就能循环字典的所有键,就像处理序列一样: d = {'name1' : 'pythontab', 'name2' : '.', 'name3' : 'com'} for key in d: print (key, ' value

  • Java web开发中加载图片路径的两种方式

    (1)   src="/image/1_it.jpg" (2)   src="http://localhost:8080/image/1_it.jpg" 其中localhost可以换位你的电脑IP,端口号也要相应改变. 以上均在基于编译器idea以及tomcat服务器开发的web中测试可行!都是要先定位到项目的位置! 以上所述是小编给大家介绍的Java web开发加载图片路径的两种方式,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

  • Android中Rxjava实现三级缓存的两种方式

    本文正如标题所说的用rxjava实现数据的三级缓存分别为内存,磁盘,网络,刚好最近在看Android源码设计模式解析与实战(受里面的ImageLoader的设计启发). 我把代码放到了我的hot项目中,github地址 源码下载地址:Rxjava_jb51.rar 1.使用concat()和first()的操作符. 2.使用BehaviorSubject. 先说BehaviorSubject的实现方法,废话不多说直接上代码, /** * Created by wukewei on 16/6/20

  • 在AOP中Spring生成代理类的两种方式

    Java 动态代理.具体有如下四步骤: 通过实现 InvocationHandler 接口创建自己的调用处理器: 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类: 通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型: 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入. 在AOP中,Spring通过生成代理类,来完成切面的织入. Spring生成代理类有2种方式. 如果目标对象实现的是一个接口,Sprin

  • Android中button实现onclicklistener事件的两种方式

    复制代码 代码如下: package com.demos; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class GetScreenActivity extends Activity { private Button fi

随机推荐