前言:

  本次要讲的是使用.Net HttpClient拼接multipark/form-data形式post上传文件和相关参数,并接收到上传文件成功后返回过来的结果(图片地址,和是否成功)。可能有很多人会说用ajax不是就可以轻松的实现吗?的确是在不存在跨域问题的前提下使用ajax上传文件,接收返回结果是最佳的选择。无奈的是我们对接的是第三方的一个上传图片的接口,而且对方并没有对我们的域名设置允许跨域,为了能够解决这一问题我们只能够通过后端请求避免跨域问题。

什么是multipart/form-data请求:

关于multipart/form-data详情查看: https://www.cnblogs.com/tylerdonet/p/5722858.html

Html上传图片按钮:

<div class="cover-hd">
<a href="javascript:;" class="a-uploadCustom">
<input type="file" id="Logoimg" onchange="OnchangeImage(this)" /></a>
</div>

使用ajax将图片文件流和相关参数传递到后端进行拼接:

注意:因为我这里调用第三方接口需要传递(appid应用程序唯一标识,random随机数,和sign签名)

<script type="text/javascript">
//后端图片上传
function OnchangeImage(obj) {
var formData = new FormData();
var files = $(obj).prop('files'); //获取到文件列表
console.log(files[]);
formData.append("imgType", );
formData.append("appId","你需要传递的参数");
formData.append("random", "你需要传递的参数");
formData.append("file", files[]);//图片文件流
formData.append("sign", "你需要传递的参数"); console.log(formData);
jQuery.support.cors = true;
$.ajax({
async: true,
contentType: false, //头部请求内容格式
dataType: 'json',
type: 'post',
data:formData,
// 告诉jQuery不要去处理发送的数据
processData: false,
url: "@Url.Action("ImageUpload", "MtVirtualStore")",//后端接收图片接口
success: function(data) {
//后端Httpclient请求成功后返回过来的结果
console.log(data);
}
});
}
</script>

后端接收图片和参数,并将图片文件流转化为图片字节类型数据:

//接收前端图片文件信息
[HttpPost]
public JsonResult ImageUpload(FormContext context)
{
HttpPostedFileBase fileData = Request.Files[];
string appId=Request["appId"];
string random=Request["random"];
string sign=Request["sign"];
string imgType=Request["imgType"];
if (fileData != null)
{
try{
string fileName = Path.GetFileName(fileData.FileName);//原始文件名称
byte[] byteFileData = ReadFileBytes(fileData);//文件流转为字节流 var resultContext =HttpClientPostUpload(byteFileData,appId,random,sign,imgType, fileName); return Json(new { code = , list = resultContext,msg="上传成功~"});
}
catch (Exception ex)
{
return Json(new { code = , msg = ex.Message });
}
}
else
{
return Json(new { code = , msg = "图片上传失败,请稍后再试~" });
}
} //文件流转化为字节
/// <summary>
/// 文件流类型转化字节类型
/// </summary>
/// <param name="fileData">文件流数据</param>
/// <returns></returns>
private byte[] ReadFileBytes(HttpPostedFileBase fileData)
{
byte[] data;
using (Stream inputStream = fileData.InputStream)
{
MemoryStream memoryStream = inputStream as MemoryStream;
if (memoryStream == null)
{
memoryStream = new MemoryStream();
inputStream.CopyTo(memoryStream);
}
data = memoryStream.ToArray();
}
return data;
}

重点,HttpClient拼接multipart/form-data形式参数post提交数据:

/// <summary>
/// 向目标地址提交图片文件参数数据
/// </summary>
/// <param name="bmpBytes">图片字节流</param>
/// <param name="appId">appid</param>
/// <param name="random">随机数</param>
/// <param name="sign">签名</param>
/// <param name="imgType">上传图片类型</param>
/// <param name="fileName">图片名称</param>
/// <returns></returns>
public string HttpClientPostUpload(byte [] bmpBytes, string appId, string random,,string sign,string imgType,string fileName)
{
using (var client = new HttpClient())
{
List<ByteArrayContent> list = new List<ByteArrayContent>(); var dataContent = new ByteArrayContent(Encoding.UTF8.GetBytes(appId));
dataContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")//内容处置标头
{
Name = "appId"
};
list.Add(dataContent); var dataContent2 = new ByteArrayContent(Encoding.UTF8.GetBytes(imgType));
dataContent2.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "imgType"
};
list.Add(dataContent2); var dataContent3 = new ByteArrayContent(Encoding.UTF8.GetBytes(random));
dataContent3.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "random"
};
list.Add(dataContent3); var dataContent4 = new ByteArrayContent(Encoding.UTF8.GetBytes(sign));
dataContent4.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "sign"
};
list.Add(dataContent4);
List<ByteArrayContent> list2 = new List<ByteArrayContent>(); var fileContent = new ByteArrayContent(bmpBytes);//填充图片字节
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name="file",
FileName=fileName
};
list.Add(fileContent); using (var content =new MultipartFormDataContent())
{
Action<List<ByteArrayContent>> act = (dataContents) =>
{//声明一个委托,该委托的作用就是将ByteArrayContent集合加入到MultipartFormDataContent中
foreach (var byteArrayContent in dataContents)
{
content.Add(byteArrayContent);
}
}; act(list);//执行act
try
{
var result = client.PostAsync("https://xxxxxx.com/imageUpload/", content).Result;//post请求
return result.Content.ReadAsStringAsync().Result;
}
catch (Exception ex)
{
return ex.Message;
} }
}
}

使用Fiddler 4 抓包查看请求的参数:

因为我们没有办法看到我们所拼接成功后的multipark/form-data形式的数据,想要看到对应拼接的请求参数可以使用 Fiddler 4 抓包工具查看:

关于Fiddler 4抓包工具的使用可以阅读该篇博客:https://www.jianshu.com/p/55f7be58a7e4

抓包获取到的multipark/form-data形式的请求参数如下图:

总结:

  写到最后才发现,原本只需要一个简单的请求就可以解决的问题因为跨域把这个问题变得如此繁琐,搞得真叫人蛋痛。这里我试过了很多种方式拼接multipark/form-data形式的请求参数,最后在坚持不懈的尝试下终于成功了。

.Net使用HttpClient以multipart/form-data形式post上传文件及其相关参数的更多相关文章

  1. Form实现无刷新上传文件并返回自定义值

    今天开发过程中遇到了这样一个问题:需要将Excel上传至服务器进行解析,但是在文档不合适的情况下希望可以不刷新页面提示用户文档不合适.冥思苦想了半天,在网上找了不少资料最终试验成功,在此分享下处理方法 ...

  2. JAVA入门[16]-form表单,上传文件

    一.如何传递参数 使用 @RequestParam 可以传递查询参数.例如:http://localhost:8092/category/detail?id=1 @RequestMapping(&qu ...

  3. jquery.form.js ajax提交上传文件

    项目中最近有用到表单提交,是带有图片上传的表单录入,需要ajax异步提交,网上找了好多例子都是只能提交上传字段一个信息的,这里整理一下.表单里有普通文本信息字段也有图片上传字段. 1.jsp代码--引 ...

  4. 模拟form表单请求上传文件

    发请求 public string CameraFileUpload(string url,string path,string serverPath,string uploadfileName) { ...

  5. HttpClient(五)-- 模拟表单上传文件

    1.maven依赖 <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId ...

  6. 传输类型为 "multipart/form-data" 的传送写法 (上传文件 和图片)

    一: 传字符的情况: 抓包数据: 传输的数据: python-request写法: 二:上传图片的情况:

  7. HttpClient多文件上传代码及普通参数中文乱码问题解决

    该随笔记录了在实际项目中使用HttpClient调用外部api,需上传文件和普通参数的代码. 笔者在使用 HttpClient 调用 http api 接口时,需要服务端上传文件和一些普通参数给 ht ...

  8. form表单上传域(type="file")的使用----上传文件

    一,单个文件的上传 1.html/jsp页面 <%@ page language="java" contentType="text/html; charset=UT ...

  9. requests上传文件,又要上传data的处理

    前话 最近在自己学着弄接口自动化框架,因为要封装一个发送请求的父类,其中有考虑到上传文件,以及同时上传文件,和传递其他字段数据,遇到点小问题 这里解决下. 实例的接口数据 参考文档 来自fastapi ...

随机推荐

  1. Cocos2d-x 3.x 学习笔记(6):Sprite SpriteFrameCache Texture2D TextureCache

    1. 概述 TextureCache是对Texture2D纹理的缓存,SpriteFrameCache是对SpriteFrame的缓存,每个SpriteFrame是对Texture2D的封装,Spri ...

  2. python 中多个装饰器的执行顺序

    python 中多个装饰器的执行顺序: def wrapper1(f1): print('in wrapper1') def inner1(*args,**kwargs): print('in inn ...

  3. 月薪12k的零基础自学前端必备手册

    随着互联网的深入发展,前端开发工程师一跃成为市场上非常抢手的人才.很多同学,包括以前做UI的.Java的.或者对于IT完全零基础的同学都想学习前端.下图是网上流传甚广的一张前端学习思维导图,很多初学者 ...

  4. rabbitMQ_integeration_spring(七)

    参考了其他博主的资料,整理成完整的代码,直接拷贝就可以测试. 一.创建一个properties文件 mq.host=127.0.0.1 mq.username=root mq.password=roo ...

  5. Jibx 只绑定需要的字段

    栗子:     binding.xml   <?xml version="1.0" encoding="UTF-8"?> <binding&g ...

  6. win10虚拟机搭建Hadoop集群(已完结)

    1 在虚拟机安装 Ubuntu 2 安装网络工具 Ubuntu最小化安装没有 ifconfig命令 sudo apt-get install net-tools 3 Ubuntu修改网卡名字 修改网卡 ...

  7. solr 新建core

    D:\tomcat\webapps\solr\solr_home 在该路径下创建一个新的core,所需文件和层级如下 test_core |-- conf |-- schema.xml |-- sol ...

  8. Linux系统下增加LV(逻辑卷)容量 、Linux系统下减少LV(逻辑卷)容量

    查看文件系统现有lv_test容量,总计4.9G,已使用3% 命令 df -h   查看现有磁盘情况,我们发现磁盘sdb共有1305个柱面,每个柱面大小是8225280 bytes (大约8M).有一 ...

  9. 集合(Collection解析 Set List Map三大集合运用)

    集合的概念:          集合是包含多个对象的简单对象,所包含的对象称为元素.集合里面可以包含任意多个对象,数量可以变化:同时对对象的类型也没有限制,也就是说集合里面的所有对象的类型可以相同,也 ...

  10. Linux下,为应用程序添加桌面图标(ubuntu18.4)

    一.桌面图标位置 Lniux下桌面图标储存路径为:/usr/share/applications 二.桌面图标格式 所有桌面图标格式均为desktop,即名为XXX.desktop 三.编辑内容(常用 ...