C#记一次http协议multipart/form-data的boundary问题

 更新时间:2022年06月09日 15:56:23   作者:地狱高速公路  
这篇文章主要介绍了C#记一次http协议multipart/form-data的boundary问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

1.问题描述

使用post方法调用上级联网厂家接口,返回http状态码415,返回信息Content type ‘application/x-www-form-urlencoded’ not supported

测试上级联网厂家接口使用的是Postman工具,工具下载地址:https://www.getpostman.com/downloads/

使用application/x-www-form-urlencoded调用接口,返回http状态码415,如图:

既然服务器无法处理请求附带的媒体格式,那么改用multipart/form-data试试?

测试后发现可以调用成功,如图:

我们都知道ContentType为application/x-www-form-urlencoded的请求头、体如何构造,如:

HttpWebRequest request = WebRequest.Create(new Uri(url)) as HttpWebRequest;
request.Method = "POST";
request.Host = Properties.Settings.Default.IP;
request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
request.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko";
request.Accept = "*/*";
request.CookieContainer = cc;
request.KeepAlive = true;
string postData = string.Format("action=cx&hphm={0}&hpzl=&jclb=&detlsh=&clpp=&clxh=&rlzl=&pfbz=&jcff=&evl=&staName={1}&detLineId=&syxz=&rqyi={2}&rqer={3}&RQXZ=JCRQ&CXJL=Jiance&cllb=&clgs=&zcrq=&zzl=&clsbdh=&syr=&ccdjrq=&page={4}&rows=10", hphm, staName, rqyi, rqer, page);
byte[] postdatabyte = Encoding.GetEncoding("utf-8").GetBytes(postData);
request.ContentLength = postdatabyte.Length;
using (Stream stream = request.GetRequestStream())
{
	stream.Write(postdatabyte, 0, postdatabyte.Length);
}
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")))
{
	string temp = reader.ReadToEnd();
}

但是!multipart/form-data的请求头与请求体该如何构造呢?像下面这样?

string url = "http://112.17.158.12:8180/intf/services/query";
HttpWebRequest request = WebRequest.Create(new Uri(url)) as HttpWebRequest;
request.Method = "POST";
request.Host = "112.17.158.12:8180";
request.ContentType = "multipart/form-data; ";
request.UserAgent = "PostmanRuntime/7.17.1";
request.Accept = "*/*";
request.KeepAlive = true;
string postData = @"jkuser=33088102&jkpasswd=33088102&jsondata={""jkid"":""R10"",""requestTime"":""20190919110603"",""body"":[{""inspstationcode"":""33088102""}]}";
byte[] postdatabyte = Encoding.GetEncoding("utf-8").GetBytes(postData);
request.ContentLength = postdatabyte.Length;
using (Stream stream = request.GetRequestStream())
{
	stream.Write(postdatabyte, 0, postdatabyte.Length);
}
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")))
{
	string temp = reader.ReadToEnd();
}

显然不对,捕获到了"远程服务器返回错误:(500)内部服务器错误。"异常,那么我们该怎么办呢?

2.解决思路

既然Postman工具使用ContentType为multipart/form-data类型post数据可以成功,那么我们写的C#程序应该也可以呀!那怎么办呢?。。。。没错!!就是抓包!

首先想到的是,用fiddler抓Postman的数据包,然后C#程序构造同样的数据包即可。

观察数据包Headers选项卡,如图:

发现Content-Type: multipart/form-data;后面跟了一个boundary=----------------------------183584948778966847113836

并且TextView选项卡如下:

WebForms选项卡如下:

所以,可以按照Headers和TextView选项卡内容构造post请求,就可以解决我们的问题了!

3.解决步骤

将ContentType加上boundary=boundary-------------------------xxxxxxxxxxxxxx

并且构造参数,如下:

string url = "http://112.17.158.12:8180/intf/services/query";
string boundary = "--------------------------" + DateTime.Now.Ticks.ToString("x");
string boundary2 = "--" + boundary;
HttpWebRequest request = WebRequest.Create(new Uri(url)) as HttpWebRequest;
request.Method = "POST";
request.Host = "112.17.158.12:8180";
request.ContentType = "multipart/form-data; boundary=" + boundary;
request.UserAgent = "PostmanRuntime/7.17.1";
request.Accept = "*/*";
request.KeepAlive = true;
StringBuilder sb = new StringBuilder();
sb.Append(boundary2 + "\r\n");
sb.Append(@"Content-Disposition: form-data; name=""jkuser""" + "\r\n\r\n");
sb.Append("33088102" + "\r\n");
sb.Append(boundary2 + "\r\n");
sb.Append(@"Content-Disposition: form-data; name=""jkpasswd""" + "\r\n\r\n");
sb.Append("33088102" + "\r\n");
sb.Append(boundary2 + "\r\n");
sb.Append(@"Content-Disposition: form-data; name=""jsondata""" + "\r\n\r\n");
sb.Append(@"{""jkid"":""R10"",""requestTime"":""20190919110603"",""body"":[{""inspstationcode"":""33088102""}]}" + "\r\n");
sb.Append(boundary2 + "--" + "\r\n");
string postData = sb.ToString();
byte[] postdatabyte = Encoding.GetEncoding("utf-8").GetBytes(postData);
request.ContentLength = postdatabyte.Length;
using (Stream stream = request.GetRequestStream())
{
    stream.Write(postdatabyte, 0, postdatabyte.Length);
}
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")))
{
    string temp = reader.ReadToEnd();
}

值得注意的是,“boundary-------------------------xxxxxxxxxxxxxx”

这么长一串东西,只是作为分隔符出现的,不必太在意它是什么东西,我将它理解为分割文本参数的这么一个东西,并且通过仔细观察发现可以发现header中contenttype的横线数量比参数中横线数量少两个且必须少两个?

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

相关文章

  • C#利用Aspose.PDF实现PDF转EPUB的完整指南

    C#利用Aspose.PDF实现PDF转EPUB的完整指南

    在 .NET 开发中,Aspose.PDF 是一个强大的库,能够帮助我们处理 PDF 文件的各种任务,包括将 PDF 转换为其他格式,如 EPUB,本文将介绍如何使用 Aspose.PDF 在 C# 中实现将 PDF 转换为 EPUB 的功能,需要的朋友可以参考下
    2025-02-02
  • 用Linq从一个集合选取几列得到一个新的集合(可改列名)

    用Linq从一个集合选取几列得到一个新的集合(可改列名)

    这篇文章主要介绍了用Linq从一个集合选取几列得到一个新的集合(可改列名),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • 详解C# 匿名对象(匿名类型)、var、动态类型 dynamic

    详解C# 匿名对象(匿名类型)、var、动态类型 dynamic

    随着C#的发展,该语言内容不断丰富,开发变得更加方便快捷,C# 的锋利尽显无疑。下面通过本文给大家分享C# 匿名对象(匿名类型)、var、动态类型 dynamic,需要的的朋友参考下吧
    2017-09-09
  • C# 设计模式系列教程-代理模式

    C# 设计模式系列教程-代理模式

    代理模式对客户端来说,隐藏了真实对象的细节及复杂性,实现了客户端(调用者)与真实对象的松耦合,提高了运行速度。
    2016-06-06
  • c#在sql中存取图片image示例

    c#在sql中存取图片image示例

    这篇文章主要介绍了c#在sql中存取图片image示例,需要的朋友可以参考下
    2014-03-03
  • C#编程获取各种电脑硬件信息的方法示例

    C#编程获取各种电脑硬件信息的方法示例

    这篇文章主要介绍了C#编程获取各种电脑硬件信息的方法,结合实例形式分析了C#获取电脑CPU、主板、硬盘、BIOS编号等信息的相关操作技巧与注意事项,需要的朋友可以参考下
    2017-08-08
  • C#自动给文章关键字加链接实现代码

    C#自动给文章关键字加链接实现代码

    这篇文章主要介绍了C#自动给文章关键字加链接实现代码,有需要的朋友可以参考一下
    2013-12-12
  • C#调用SQLite的方法实例分析

    C#调用SQLite的方法实例分析

    这篇文章主要介绍了C#调用SQLite的方法,较为详细的介绍了SQLite的功能与特点,并实例分析了C#调用SQLite的相关技巧,需要的朋友可以参考下
    2015-06-06
  • 使用C#实现对任意区域任意大小的截图

    使用C#实现对任意区域任意大小的截图

    这篇文章主要为大家详细介绍了如何使用C#实现简单的截图功能,可以对任意区域任意大小的截图,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • c# 异步编程入门

    c# 异步编程入门

    这篇文章主要介绍了c# 异步编程入门的相关资料,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-03-03

最新评论