<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ù)實踐]請查收

          共 3642字,需瀏覽 8分鐘

           ·

          2022-01-02 16:09


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


          01

          荒腔走板

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

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

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

          02

          頭腦風(fēng)暴


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

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

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



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

          選中文件,點擊[Send the file]按鈕,提交表單,會發(fā)出如下請求

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

          03

          照葫蘆畫瓢

          ? ? ? ?以上就是常規(guī)的Html表單上傳文件的協(xié)議分析,回到本文主題, 這次會使用HttpClient編碼形式發(fā)送只含有一個文件表單域的請求?(依舊利用的multipart/form-data媒體類型), 這也是下文的實現(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是一個集合類型。
          ????????????????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);
          ????????????}
          ????????}
          ????}
          }

          ?請注意,我使用一個隨機的GUID做為每個表單域的劃分邊界,這里我向MultipartFormDataContent只插入了一個文件表單閾值,這樣就做到了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;
          }

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

          3.3 授人以漁

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

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

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

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

          #?全文總結(jié)

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

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


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


          點分享


          點點贊


          點在看

          瀏覽 45
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  国产高清在线视频 | 亚洲精品一级黄色电影 | 日本性爱无码 | 靠逼视频网站在线观看 | 影音先锋一区二区三区 |