<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          童鞋,[HttpClient發(fā)送文件的技術(shù)實(shí)踐]請(qǐng)查收

          共 3642字,需瀏覽 8分鐘

           ·

          2021-12-20 16:48


          ? ? 昨天有童鞋在群里面問(wèn):怎么使用HttpClient發(fā)送文件?


          01

          荒腔走板

          ? ? ? 之前我寫(xiě)了一個(gè)《ABP小試牛刀之上傳文件》,主要體現(xiàn)的是服務(wù)端,上傳文件的動(dòng)作是由前端小姐姐完成的, 我還真沒(méi)有用HttpClient編程方式發(fā)送過(guò)文件。

          不過(guò)HttpClient的動(dòng)作遵守Web協(xié)議,盲猜httpclient按照前端multipart/form-data媒體類型發(fā)送文件應(yīng)該也是可行的。

          花一個(gè)小時(shí)閱讀了MDN Web協(xié)議,寫(xiě)就了HttpClient發(fā)送文件的實(shí)例, 看官自取。

          02

          頭腦風(fēng)暴


          ? ? ? 我們跟隨常見(jiàn)的表單上傳文件思路來(lái)實(shí)現(xiàn)HttpClinet上傳文件。

          multipart/form-data是一種由多部分表單域值組成的媒體類型,每部分由邊界線(一個(gè)由'--'開(kāi)始的字符串)劃分。

          如下面的表單, 有三個(gè)待提交input表單字段



          ??
          ??Check
          ??myFile">
          ??

          選中文件,點(diǎn)擊[Send the file]按鈕,提交表單,會(huì)發(fā)出如下請(qǐng)求

          請(qǐng)觀察由boundary劃分的每個(gè)表單域和值, 其中myFile是一個(gè)文件表單域,?這個(gè)文件域需要單獨(dú)指定Content-Type類型。

          03

          照葫蘆畫(huà)瓢

          ? ? ? ?以上就是常規(guī)的Html表單上傳文件的協(xié)議分析,回到本文主題, 這次會(huì)使用HttpClient編碼形式發(fā)送只含有一個(gè)文件表單域的請(qǐng)求?(依舊利用的multipart/form-data媒體類型), 這也是下文的實(shí)現(xiàn)思路。

          下面是httpclient向localhost:5000/upload地址上傳文件, 服務(wù)器返回圖片的base64編碼字符串。

          3.1 客戶端

          using?System;
          using?System.IO;
          using?System.Net.Http;
          using?System.Net.Http.Headers;
          using?System.Text;
          using?System.Threading.Tasks;

          namespace?ConsoleApp3
          {
          ????class?Program
          ????{
          ????????static?readonly?HttpClient?client?=?new?HttpClient();
          ????????static?async?Task?Main()
          ????????{
          ????????????try
          ????????????{
          ????????????????byte[]?bytes;
          ????????????????using?(var?bodyStream?=?new?FileStream(@"D:\001.png",?FileMode.Open))
          ????????????????{
          ????????????????????using?var?m?=?new?MemoryStream();
          ????????????????????await?bodyStream.CopyToAsync(m);
          ????????????????????bytes?=?m.ToArray();
          ????????????????}
          ??????????????
          ??//?1.?準(zhǔn)備文件表單域和值
          ????????????????var?byteArrayContent?=?new?ByteArrayContent(bytes);
          ????????????????byteArrayContent.Headers.ContentType?=?MediaTypeHeaderValue.Parse("image/png");

          ????????????????// 2. ?向MultipartFormDataContent插入準(zhǔn)備好的文件表單域值,?注意MultipartFormDataContent是一個(gè)集合類型。
          ????????????????var?response?=?await?client.PostAsync("http://localhost:5000/upload",?new?MultipartFormDataContent(Guid.NewGuid().ToString())
          ????????????????????{
          ????????????????????????{?byteArrayContent,?"uploadedFile",?"\"001ggg.png\""}
          ????????????????????});

          ????????????????response.EnsureSuccessStatusCode();
          ????????????????var?responseBody?=?await?response.Content.ReadAsStringAsync();
          ????????????????Console.WriteLine(responseBody);
          ????????????}
          ????????????catch?(HttpRequestException?e)
          ????????????{
          ????????????????Console.WriteLine("\nException?Caught!");
          ????????????????Console.WriteLine("Message?:{0}?",?e.Message);
          ????????????}
          ????????}
          ????}
          }

          ?請(qǐng)注意,我使用一個(gè)隨機(jī)的GUID做為每個(gè)表單域的劃分邊界,這里我向MultipartFormDataContent只插入了一個(gè)文件表單閾值,這樣就做到了HttpClient發(fā)送文件。?文件表單域值:? { byteArrayContent, "uploadedFile", "\"001ggg.png\""}?中的參數(shù)2:?字段名稱很重要,要與下面服務(wù)端的參數(shù)名匹配。

          3.2 服務(wù)端

          上傳文件的代碼在ABP小試牛刀之上傳文件一文已經(jīng)體現(xiàn),本次截取接收文件上傳的核心代碼

          [Consumes("multipart/form-data")]
          [Route("upload")]
          [ProducesResponseType(typeof(Guid),?200)]
          [HttpPost]
          public?async?Task?UploadAsync(IFormFile?
          uploadedFile)
          {
          ? ? ?var?formFileName?=?uploadedFile.FileName;
          ?????if?(!new[]?{?".png",?".jpg",?".bmp"?}.Any((item)?=>?formFileName.EndsWith(item)))
          ?????{
          ?????? ? ? throw?new?NotImplementedException("您上傳的文件格式必須為png、jpg、bmp中的一種");
          ?????}
          ? ? ?byte[]?bytes;
          ?????using?(var?bodyStream?=?uploadedFile.OpenReadStream())
          ?????{
          ???????? using?(var?m?=?new?MemoryStream())
          ???????? {
          ?????????? ?await?bodyStream.CopyToAsync(m);
          ?????????? ?bytes?=?m.ToArray();
          ?????????}
          ?????}
          ?????var?base64?=?Convert.ToBase64String(bytes);
          ?????return?base64;
          }

          碼甲哥從不打誑語(yǔ),啟動(dòng)客戶端/服務(wù)端

          3.3 授人以漁

          成熟的技術(shù)必須有成熟的調(diào)試和監(jiān)測(cè)手段!

          成熟的技術(shù)必須有成熟的調(diào)試和監(jiān)測(cè)手段!

          成熟的技術(shù)必須有成熟的調(diào)試和監(jiān)測(cè)手段!

          每當(dāng)做web開(kāi)發(fā)出現(xiàn)阻塞的時(shí)候,我就掏出web利器Fiddler,跟著Fiddler去策馬奔騰吧。

          #?全文總結(jié)

          1.對(duì)常規(guī)html表單上傳文件的功能,做協(xié)議級(jí)分析。2.根據(jù)分析結(jié)果,HttpClient使用同樣的姿勢(shì)發(fā)送文件: 使用multipart/form-data(多部分表單媒體類型)發(fā)起上傳請(qǐng)求。

          [1]?媒體類型MIME:?https://developer.mozilla.org/zhCN/docs/Web/HTTP/Basics_of_HTTP/MIME_types


          我是有態(tài)度的馬甲,不追熱點(diǎn),原創(chuàng)輸出 # 八股文 # 硬核干貨 # 職場(chǎng)心得 #,歡迎關(guān)注。


          點(diǎn)分享


          點(diǎn)點(diǎn)贊


          點(diǎn)在看

          瀏覽 41
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  俺去也WWW在线视频 | 天天日夜夜爽 | 激情久久婷婷 | 色婷婷www | 亚州无码高清视频在线观看 |