专栏首页追逐时光.Net使用HttpClient以multipart/form-data形式post上传文件及其相关参数

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

前言:

  本次要讲的是使用.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[0]);
        formData.append("imgType", 1);
        formData.append("appId","你需要传递的参数");
        formData.append("random", "你需要传递的参数");
        formData.append("file", files[0]);//图片文件流
        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[0];
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 = 1, list = resultContext,msg="上传成功~"});
}
catch (Exception ex)
{
return Json(new { code = 0, msg = ex.Message });
}
}
else
{
return Json(new { code = 0, 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形式的请求参数,最后在坚持不懈的尝试下终于成功了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Linux Centos上安装 MySQL 8.0.16

      因为我在我的Linux上安装的是Centos系统,本次安装对于我们这些不太熟悉Liunx操作系统的小白使用的是镜像下载安装,这样子我们只需要输入一些简单的命...

    追逐时光
  • Net微信网页开发之使用微信JS-SDK获取当前地理位置

      前段时间有一个关于通过获取用户当前经纬度坐标,计算出该用户距离某指定地点之间的距离。因为做这个项目需要能够获取到比较精确的经纬度坐标,刚开始使用的是百度地图...

    追逐时光
  • 微信小程序开发之多图片上传+服务端接收

      业务需求,这次需要做一个小程序同时选中三张图片一起上传到服务端,后端使用的.NET WEBAPI接收数据保存。

    追逐时光
  • Android RecyclerView浅析(分类型)

    整体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoratio...

    IT大飞说
  • JavaScript OOP(一)之构造函数与new命令

     面向对象编程:Object Oriented Programming,简称OOP。 典型的oop语言,如hava、c++,存在着类的概念,类就是对象的模板 (...

    用户1149564
  • abstract virtaul override new 及多态

    abstract 修饰符可以和类、方法、属性、索引器及事件一起使用。在类声明中使用 abstract 修饰符以指示某个类只能是其他类的基类。标记为抽象或包含在抽...

    lulianqi
  • 将表格导出为excel

    ProsperLee
  • 挑战程序竞赛系列(74):4.3强连通分量分解(1)

    挑战程序竞赛系列(74):4.3强连通分量分解(1) 传送门:POJ 2186: Popular Cows 题意: 每头牛都想成为牛群中的红人。给定N头牛的牛...

    用户1147447
  • 挑战程序竞赛系列(70):4.7后缀数组(2)

    挑战程序竞赛系列(70):4.7后缀数组(2) 传送门:POJ 1509: Glass Beads 题意: The description of the ne...

    用户1147447
  • .NET代码错误日志

    DougWang

扫码关注云+社区

领取腾讯云代金券