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

 更新时间:2021年05月28日 10:28:34   作者:薄心之心  
现在很多B/S系统的开发都是通过API方式来进行的,一般服务端会开放一个API接口,客户端调用API接口来实现图片或文件上传的功能,感兴趣的可以了解一下

现在很多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参数,技术上是完全行的通的。
 
那么,“标准答案”里的那些区别是怎么回事?

在我大万维网世界中,TCP就像汽车,我们用TCP来运输数据,它很可靠,从来不会发生丢件少件的现象。但是如果路上跑的全是看起来一模一样的汽车,那这个世界看起来是一团混乱,送急件的汽车可能被前面满载货物的汽车拦堵在路上,整个交通系统一定会瘫痪。为了避免这种情况发生,交通规则HTTP诞生了。HTTP给汽车运输设定了好几个服务类别,有GET, POST, PUT, DELETE等等,HTTP规定,当执行GET请求的时候,要给汽车贴上GET的标签(设置method为GET),而且要求把传送的数据放在车顶上(url中)以方便记录。如果是POST请求,就要在车上贴上POST的标签,并把货物放在车厢里。当然,你也可以在GET的时候往车厢内偷偷藏点货物,但是这是很不光彩;也可以在POST的时候在车顶上也放一些数据,让人觉得傻乎乎的。HTTP只是个行为准则,而TCP才是GET和POST怎么实现的基本。

但是,我们只看到HTTP对GET和POST参数的传送渠道(url还是requrest body)提出了要求。“标准答案”里关于参数大小的限制又是从哪来的呢?

在我大万维网世界中,还有另一个重要的角色:运输公司。不同的浏览器(发起http请求)和服务器(接受http请求)就是不同的运输公司。 虽然理论上,你可以在车顶上无限的堆货物(url中无限加参数)。但是运输公司可不傻,装货和卸货也是有很大成本的,他们会限制单次运输量来控制风险,数据量太大对浏览器和服务器都是很大负担。业界不成文的规定是,(大多数)浏览器通常都会限制url长度在2K个字节,而(大多数)服务器最多处理64K大小的url。超过的部分,恕不处理。如果你用GET服务,在request body偷偷藏了数据,不同服务器的处理方式也是不同的,有些服务器会帮你卸货,读出数据,有些服务器直接忽略,所以,虽然GET可以带request body,也不能保证一定能被接收到哦。

好了,现在你知道,GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。

GET和POST还有一个重大区别,简单的说:

GET产生一个TCP数据包;POST产生两个TCP数据包。

长的说:

           对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);

而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

         也就是说,GET只需要汽车跑一趟就把货送到了,而POST得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。

         因为POST需要两步,时间上消耗的要多一点,看起来GET比POST更有效。因此Yahoo团队有推荐用GET替换POST来优化网站性能。但这是一个坑!跳入需谨慎。为什么?

1. GET与POST都有自己的语义,不能随便混用。

2. 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。

3. 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

前段时间碰到需要使用POST请求上传图片的功能,好久没写了,重新整理下函数,方便后续使用。

为了使用的通用性,函数做了一定的封装,具体代码如下:

public static void UploadImage(string uploadUrl,string imgPath,string fileparameter="file")
        {
            HttpWebRequest request = WebRequest.Create(uploadUrl) as HttpWebRequest;
            request.AllowAutoRedirect = true;
            request.Method = "POST";

            string boundary = DateTime.Now.Ticks.ToString("X"); // 随机分隔线
            request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary;
            byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
            byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");

            int pos = imgPath.LastIndexOf("/");
            string fileName = imgPath.Substring(pos + 1);

            //请求头部信息
            StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name=\""+fileparameter+"\";filename=\"{0}\"\r\nContent-Type:application/octet-stream\r\n\r\n", fileName));
            byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sbHeader.ToString());

            FileStream fs = new FileStream(imgPath, FileMode.Open, FileAccess.Read);
            byte[] bArr = new byte[fs.Length];
            fs.Read(bArr, 0, bArr.Length);
            fs.Close();

            Stream postStream = request.GetRequestStream();
            postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
            postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
            postStream.Write(bArr, 0, bArr.Length);
            postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
            postStream.Close();

            HttpWebResponse response = request.GetResponse() as HttpWebResponse;
            Stream instream = response.GetResponseStream();
            StreamReader sr = new StreamReader(instream, Encoding.UTF8);
            string content = sr.ReadToEnd();
        }

使用起来也比较方便,调用方法如下:

UploadImage("图上上传接口地址","本地图片文件路径","接口提供的上传参数名称,没有默认为file");

例如:UploadImage("http://xxx.com/upload","C:/test.jpg","upload");

到此这篇关于C#调用HTTP POST请求上传图片的示例代码的文章就介绍到这了,更多相关C# HTTP POST请求上传图片内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#获取关键字附近文字算法实例

    C#获取关键字附近文字算法实例

    这篇文章主要介绍了C#获取关键字附近文字算法,实例分析了文字查找算法的原理与实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • C#实现鼠标拖拽无边框浮动窗体的方法

    C#实现鼠标拖拽无边框浮动窗体的方法

    一般情况下,在标题栏中按住鼠标左键不放即可实现拖动操作,当做浮动窗体时,如果包含窗体边框,那么界面给使用者的感觉将很不友好,因此本文给大家介绍了C#实现鼠标拖拽无边框浮动窗体的方法,感兴趣的朋友可以参考下
    2024-04-04
  • C#中逆变的实际应用场景详解

    C#中逆变的实际应用场景详解

    在好多的.net的书籍中都看到过逆变和协变的概念,也在网上搜了一些关于这两个概念的解释,但是一直感觉似懂非懂的,直到最近在项目中实际遇到了一个问题,恰好用到了逆变,下面这篇文章主要给大家介绍了关于C#中逆变的实际应用场景,需要的朋友可以参考下
    2022-01-01
  • 详解C#如何手动改变自制窗体的大小

    详解C#如何手动改变自制窗体的大小

    这篇文章主要为大家详细介绍了在C#中如何实现手动改变自制窗体的大小,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-03-03
  • C#实现的字符串转MD5码函数实例

    C#实现的字符串转MD5码函数实例

    这篇文章主要介绍了C#实现的字符串转MD5码函数,结合简单实例形式分析了C#字符串的转换、遍历、加密等操作技巧,需要的朋友可以参考下
    2016-07-07
  • C#在新建线程中使用Timer无效问题及解决

    C#在新建线程中使用Timer无效问题及解决

    这篇文章主要介绍了C#在新建线程中使用Timer无效问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • C#中的事件介绍

    C#中的事件介绍

    这篇文章主要介绍了C#中的事件介绍,本文对C#事件的语法、定义方法、调用方法等做了讲解,需要的朋友可以参考下
    2015-01-01
  • C#程序连接数据库及读取数据库中字段的简单方法总结

    C#程序连接数据库及读取数据库中字段的简单方法总结

    包括C#连接Access、Oracle或者SQL Server,这里整理了一些C#连接数据库及从读取数据库中字段的简单方法总结,需要的朋友可以参考下
    2016-05-05
  • Unity利用XML制作一个简易的登录系统

    Unity利用XML制作一个简易的登录系统

    这篇文章主要介绍了如何在Unity中利用XML文件制作一个简易的登录系统,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-03-03
  • 配置C#的系统环境变量的方法

    配置C#的系统环境变量的方法

    配置C#的系统环境变量的方法...
    2007-03-03

最新评论