前言:

  本次要讲的是使用.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. C#3.0新增功能10 表达式树 03 支持表达式树的框架类型

    连载目录    [已更新最新开发文章,点击查看详细] 存在可与表达式树配合使用的 .NET Core framework 中的类的大型列表. 可以在 System.Linq.Expressions 查 ...

  2. [leetcode] #213 House Robber II Medium (medium)

    原题链接 比子母题House Robber多了一个条件:偷了0以后,第n-1间房子不能偷. 转换思路为求偷盗[0,n-1)之间,以及[1,n)之间的最大值. 用两个DP,分别保存偷不偷第0间房的情况. ...

  3. python购物车升级版

    各文件内容 前言 功能架构等请参考前一篇博客,此篇博客为进阶版的存代码展示. 详细文件内容 启动文件 starts.py启动文件 import os import sys BASE_DIR = os. ...

  4. 织梦(dede)底层模板概念、常用底层模板字段

    织梦(dede)底层模板概念.常用底层模板字段 一.底层模板的概念以及调用方式: 1. 什么是底层模板? 底层模板不是一个模板! 他就是在实际页面当中所要显示的具体内容: 2. 底层模板的应用: 调用 ...

  5. 带新手玩转MVC——不讲道理就是干(下)

    带新手玩转MVC——不讲道理就是干(下) 前言:废话不多说,直接开干 完整案例演示 案例代码 LoginServlet package servlet; import domain.User; imp ...

  6. JavaScript常用语句

    JavaScript常用语句 语句 语法 说明 简单语句 : 语句以:分号结束 语句块 {} 将一组语句组成语句块,ES中没有语句块作用域,也可用作对象字面量 添加标签语句 label 给代码添加标签 ...

  7. IrisSkin2.dll 添加皮肤

    使用说明:把控件拖到你的form上,只需一行代码,即可实现整个form包括其所有控件的皮肤的更换,总共有几十套皮肤供使用,非常方便.省去你设计开发软件皮肤系统的时间和精力.全部源代码就一行: skin ...

  8. thinkphp phpexcel导出返回乱码

    今天做了一个excel文件导出的功能  可是无论怎么改网上怎么搜答案什么缓冲啊charset=UTF-8'a都不起效 <?phpnamespace app\admin\controller;us ...

  9. spring 注解验证@NotNull等使用方法

    @Null 被注释的元素必须为null@NotNull 被注释的元素不能为null@AssertTrue 被注释的元素必须为true@AssertFalse 被注释的元素必须为false@Min(va ...

  10. c#小灶——使用visual studio编写第一个程序

    虽然,写程序有文本编辑器和编译器就已经足够,但是,我们为了增加工作效率还是要使用IDE. 我们接下来所有的教程都将会在visual studio中实现,visual studio简称vs,是微软开发的 ...