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

在我大万维网世界中,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请求上传图片内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C#使用Http Post方式传递Json数据字符串调用Web Service

    引言 前段时间一直在做一个ERP系统,随着系统功能的完善,客户端(CS模式)变得越来越臃肿.现在想将业务逻辑层以下部分和界面层分离,使用Web Service来做.由于C#中通过直接添加引用的方来调用Web Service的方式不够灵活,故采取手动发送Http请求的方式来调用Web Service.最后选择使用Post方式来调用Web Service,至于安全性和效率暂不考虑.在学习使用的过程,遇到了很多问题,也花了很长时间来解决,网上相关的帖子很少,如果各位在使用的过程中有一些问题难以解决,可

  • C#模拟http 发送post或get请求的简单实例

    private string HttpPost(string Url, string postDataStr) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = Enco

  • 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#发送HttpPost请求来调用WebService的方法

    复制代码 代码如下: void UpdateContactSign()        {           string ServerPage ="http://localhost/WebService/MyService.asmx";            try            {                //ServerPage += "?op=TangramAction";                ServerPage += "

  • 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参

  • Java调用微信支付功能的方法示例代码

    Java 使用微信支付 前言百度搜了一下微信支付,都描述的不太好,于是乎打算自己写一个案例,希望以后拿来直接改造使用. 因为涉及二维码的前端显示,所以有前端的内容 一. 准备工作 所需微信公众号信息配置 APPID:绑定支付的APPID(必须配置) MCHID:商户号(必须配置) KEY:商户支付密钥,参考开户邮件设置(必须配置) APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置) 我这个案例用的是尚硅谷一位老师提供的,这里不方便提供出来,需要大家自己找,或者公司提供 二

  • JavaScript/TypeScript 实现并发请求控制的示例代码

    场景 假设有 10 个请求,但是最大的并发数目是 5 个,并且要求拿到请求结果,这样就是一个简单的并发请求控制 模拟 利用 setTimeout 实行简单模仿一个请求 let startTime = Date.now(); const timeout = (timeout: number, ret: number) => { return (idx?: any) => new Promise((resolve) => { setTimeout(() => { const compa

  • 利用js实现Ajax并发请求限制请求数量的示例代码

    出现问题描述:当不确定异步请求个数时,为防止当一瞬间发生上百个http请求时,导致堆积了无数调用栈进而导致内存溢出问题. 要求:将同一时刻并发请求数量控制在3个以内,同时还要尽可能快速的拿到响应的结果. 同面试问题: 实现一个批量请求函数 multiRequest(urls, maxNum),要求如下: 要求最大并发数 maxNum 每当有一个请求返回,就留下一个空位,可以增加新的请求 所有请求完成后,结果按照 urls 里面的顺序依次打出 1.基于Promise.all实现Ajax的串行和并行

  • webpack+vuex+axios 跨域请求数据的示例代码

    本文介绍了webpack+vuex+axios 跨域请求数据的示例代码,分享给大家,具体如下: 使用vue-li 构建 webpack项目,修改bulid/config/index.js文件 dev: { env: require('./dev.env'), port: process.env.PORT || 8080, autoOpenBrowser: true, assetsSubDirectory: 'static', assetsPublicPath: '/', proxyTable:

  • C#调用摄像头实现拍照功能的示例代码

    前言 老师要求我们学生做一套拍照身份验证系统,经过长时间的学习,有了这篇文章,希望能帮到读者们. 正文 首先介绍本文的主角:AForge 创建一个C#项目,引用必备的几个DLL AForge.dll AForge.Controls.dll AForge.Imaging.dll AForge.Math.dll AForge.Video.DirectShow.dll AForge.Video.dll 这些DLL读者们可以在文末下载我附带的Demon 引用必要的命名空间 using AForge.Co

  • SpringMVC框架实现上传图片的示例代码

    一.创建图片虚拟目录 在上传图片之前,先要设置虚拟目录(以IDEA为例) 打开工具栏的运行配置Edit Configurations 添加物理目录和并设置虚拟目录路径 添加img图片在img文件夹内 测试访问:http://localhost:8080/img/img.jpg 二.SpringMVC上传头像 1.SpringMVC对多部件类型的解析 上传图片SpringMVC.xml配置 在页面form中提交enctype="multipart/form-data"的数据时,需要spr

  • vue的全局变量和全局拦截请求器的示例代码

    做的产品证书管理系统使用的是VueJs和ElementUI,现将遇到的一些知识点记录一下. VUe全局变量的实现 全局变量专用模块Global.vue是以一个特定模块来组织管理全局变量,需要引用的地方导入该模块即可.使用方法如下: 将全局变量模块挂载到Vue.prototype里,在程序入口的main.js里加下面代码: import Global from '../components/Global.vue' Vue.prototype.global = Global 挂载后,在需要引用全局变

  • 利用Promise自定义一个GET请求的函数示例代码

    写在最前面 近期 review 自己以前的代码的时候,看到 promise 的使用方法,用的比较模糊.含义不清,用法凌乱,这里重新温习一下基础知识. 前言 JavaScript 是单线程工作,但是浏览器是多线程的.为了更好的完成我们程序的任务.Promise 异步的操作就由此诞生了. 一个 Promise 就是一个代表了异步操作最终完成或者失败的结果对象. 怎么使用? 语法 基本 new Promise( function(resolve, reject) {...} /* executor *

  • C#调用RabbitMQ实现消息队列的示例代码

    前言 我在刚接触使用中间件的时候,发现,中间件的使用并不是最难的,反而是中间件的下载,安装,配置才是最难的. 所以,这篇文章我们从头开始学习RabbitMq,真正的从头开始. 关于消息队列 其实消息队列没有那么神秘,我们这样想一下,用户访问网站,最终是要将数据以HTTP的协议的方式,通过网络传输到主机的某个端口上的. 那么,接收数据的方式是什么呢?自然是端口监听啦. 那消息队列是什么就很好解释了? 它就是端口监听,接到数据后,将数据排列起来. 那这件事,我们不用中间件能做吗? 当然能做啦,写个T

随机推荐