.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形式的請求參數,最后在堅持不懈的嘗試下終於成功了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM