这一阵子因为项目需要要对接别家公司的restful接口,其中有一个接口是上传视频文件。接着上网找找资料。后来文件是上传成功了,但上服务器一看,文件没有后缀,我勒个去,这是什么个鬼。接着继续找资料,最终发现是因为在文件数据后面没加上“\r\n”引起的,特发此博文备忘。在此感谢【小伊同学】的《c#代码发送post请求,上传文件》https://www.cnblogs.com/yinq/p/6045995.html和【imEgo】的《HTTP POST上传文件格式说明》http://blog.sina.com.cn/s/blog_73b633110101jwxm.html。

 public static Response FileLoadRequest(string url, string filePath, string rename = "")
{
Response httpResponse = null;
string fileName = FileHelper.GetFileName(filePath);
string boundary = "ceshi";
string Enter = "\r\n"; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "multipart/form-data;charset=utf8;boundary=" + boundary; //boundary这个属性很重要
//进行Session持久化
request.CookieContainer = cookie; #region 将参数写入请求流中
Stream RequestStream = request.GetRequestStream();
string fileContentStr = "--" + boundary + Enter
+ "Content-Type:application/octet-stream" + Enter
+ "Content-Disposition: form-data; name=\"file\"; filename=\"" + fileName + "\"" + Enter + Enter;
var fileContentStrByte = Encoding.UTF8.GetBytes(fileContentStr); FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
byte[] filedata = new byte[fs.Length];
fs.Read(filedata, , Convert.ToInt32(fs.Length));
fs.Close(); RequestStream.Write(fileContentStrByte, , fileContentStrByte.Length);
RequestStream.Write(filedata, , filedata.Length); //在文件数据末尾要加上“\r\n”
string EndStr1 = Enter;
var EndStr1Byte = Encoding.UTF8.GetBytes(EndStr1);
RequestStream.Write(EndStr1Byte, , EndStr1Byte.Length); if (rename != "")
{
string fileNameStr = "--" + boundary + Enter
+ "Content-Disposition: form-data; name=\"file_name\"" + Enter + Enter
+ rename;
var fileNameStrByte = Encoding.UTF8.GetBytes(fileNameStr);
RequestStream.Write(fileNameStrByte, , fileNameStrByte.Length);
} //在流末尾要加上--ceshi--的分隔符
string EndStr = Enter + "--" + boundary + "--";
var EndStrByte = Encoding.UTF8.GetBytes(EndStr);
RequestStream.Write(EndStrByte, , EndStrByte.Length);
#endregion string responseMessage = string.Empty;
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{ StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
responseMessage = sr.ReadToEnd();
httpResponse = JsonConvert.DeserializeObject<Response>(responseMessage);
response.Close();
}
}
catch (WebException ex)
{
Program.log.Error(string.Format("System.Net.WebException:UrlGetRequest出错,URL='{0}':", request.RequestUri), ex);
}
catch (Exception ex)
{
Program.log.Error(string.Format("UrlGetRequest出错,URL='{0}':", request.RequestUri), ex);
} return httpResponse;
}

下面引用下RFC的Sample:

Content-Type: multipart/form-data, boundary=AaB03x

--AaB03x
Content-Disposition: form-data; name="field1" Joe Blow
--AaB03x
Content-Disposition: form-data; name="pics"; filename="file1.txt"
Content-Type: text/plain ... contents of file1.txt ...
--AaB03x--

首先,在Content-Type中,boundary这个属性一定要加,但boundary属性值随意设置成什么都行,它不会出现在要上传的数据里,只是起到分隔的作用。上面是设置成“Aab03x”。重点来了:每个参数之前需要加上“--boundary”,注意前面有“--”。参数最后结尾要加“--boundary--”。文件数据后要跟上“\r\n”(我就是因为没加“\r\n,所以没有文件后缀”)在上传文件的那一个参数的Content-Type:是根据上传文件的后缀进行设置的,详细对照表请参照:http://tool.oschina.net/commons/。如果不想根据文件后缀进行填充的话,可以直接用“application/octet-stream”。

HTTP POST上传文件说明及注意事项的更多相关文章

  1. springmvc上传文件方法及注意事项

    本文基于注解的配置,敬请留意  基于注解整合 一.springmvc为我们提供两种上传方式配置: org.springframework.web.multipart.commons.CommonsMu ...

  2. ASP.NET MVC中使用表单上传文件时的注意事项

    最近了好久没写ASP.NET 使用HTML的FORM来上传文件了,结果写了个文件上传发现ASP.NET MVC的Controller中老是读取不到上传的文件. MVC的View(Index.cshtm ...

  3. 上传文件到hdfs注意事项

    我在MapReduceInput下创建CFItemSet文件夹,下面有itemSet.txt. 我想上传到cf下,然后想着hdfs上会显示cf/itemSet.txt. hdfs dfs -put i ...

  4. IE8/9 JQuery.Ajax 上传文件无效

    IE8/9 JQuery.Ajax 上传文件有两个限制: 使用 JQuery.Ajax 无法上传文件(因为无法使用 FormData,FormData 是 HTML5 的一个特性,IE8/9 不支持) ...

  5. 三种上传文件不刷新页面的方法讨论:iframe/FormData/FileReader

    发请求有两种方式,一种是用ajax,另一种是用form提交,默认的form提交如果不做处理的话,会使页面重定向.以一个简单的demo做说明: html如下所示,请求的路径action为"up ...

  6. asp.net mvc 上传文件

    转至:http://www.cnblogs.com/fonour/p/ajaxFileUpload.html 0.下载 http://files.cnblogs.com/files/fonour/aj ...

  7. app端上传文件至服务器后台,web端上传文件存储到服务器

    1.android前端发送服务器请求 在spring-mvc.xml 将过滤屏蔽(如果不屏蔽 ,文件流为空) <!-- <bean id="multipartResolver&q ...

  8. .net FTP上传文件

    FTP上传文件代码实现: private void UploadFileByWebClient() { WebClient webClient = new WebClient(); webClient ...

  9. 通过cmd完成FTP上传文件操作

    一直使用 FileZilla 这个工具进行相关的 FTP 操作,而在某一次版本升级之后,发现不太好用了,连接老是掉,再后来完全连接不上去. 改用了一段时间的 Web 版的 FTP 工具,后来那个页面也 ...

随机推荐

  1. mongodb获取具体某一天的查询语句

    比如我要查询截止日期为2010-12-21这一天的数据记录.方法一. db.集合名.find({con_date:new Date("2010/12/21")})1方法二. db. ...

  2. 2016级算法第三次上机-C.AlvinZH的奇幻猜想——三次方

    905 AlvinZH的奇幻猜想--三次方 思路 中等题.题意简单,题目说得简单,把一个数分成多个立方数的和,问最小立方数个数. 脑子转得快的马上想到贪心,从最近的三次方数往下减,反正有1^3在最后撑 ...

  3. 编程开发之--Oracle数据库--存储过程和存储函数(1)

    1.存储过程和存储函数 描述:指存储在数据库中供所有用户程序调用的子程序叫做存储过程.存储函数 区别:存储函数可以通过return子句返回一个函数的值 (1)存储过程 语法:create [or re ...

  4. Linux基本结构

    Linux 的基本目录结构:     基本介绍:      Linux 的文件系统是采用级层式的树状目录结构,在此结构中的最上层是根目录“/”,然后再次目录下载创建其他的目录. 经典的一句话:linu ...

  5. Saiku2.6 保存查询后,重新打开报 Error Loading Query错误。

    发现Saiku2.6的查询保存后重新打开就会报如下错误,同等的Schema文件和数据库环境在3.15环境里面打开是一切正常的. 后面对比了一下2.6和3.15的启动环境,发现有些差异的地方. 2.6启 ...

  6. python update()

    Python 字典 update() 函数把字典参数 dict2 的 key/value(键/值) 对更新到字典 dict 里. dict.update(dict2) 如果dict2里的键和dict1 ...

  7. 接口自动化之unittest+ddt

    我在上一篇(https://www.cnblogs.com/wlyhy/p/10083318.html) 文章整理了unittest的模板,但在后续学习中,发现还有许多值得优化的地方.例如在我们设计测 ...

  8. 基础篇:4.2)规范化:3d软件工程图纸用模板

    本章目的:分享一些国标标准模板,方便作图时使用 这篇博文的内容作者会定时的更新 1.工程图模板 drawing template 定义 三维机械设计软件中的一种文件类型.通过标准化定制和使用该文件,可 ...

  9. 使用 json_serializable (flutter packages pub run build_runner build) 问题

    命令: flutter packages pub run build_runner build 使用 build_runner 生成 .g.dart 文件 flutter packages pub r ...

  10. Python3.0版本 从听说python可以做爬虫到自己第一成功做出爬虫的经历

    前言 我自己是个python小白,工作也不是软件行业,但是日常没事时喜欢捣鼓一些小玩意,自身有点C语言基础. 听说python很火,可以做出爬虫去爬一些数据图片视频之类的东东,我的兴趣一下子就来了.然 ...