童鞋,[HttpClient发送文件的技术实践]请查收

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了童鞋,[HttpClient发送文件的技术实践]请查收相关的知识,希望对你有一定的参考价值。

    昨天有童鞋在群里面问:怎么使用HttpClient发送文件?

01

荒腔走板

      之前我写了一个《ABP小试牛刀之上传文件》,主要体现的是服务端,上传文件的动作是由前端小姐姐完成的, 我还真没有用HttpClient编程方式发送过文件。

不过HttpClient的动作遵守Web协议,盲猜httpclient按照前端multipart/form-data媒体类型发送文件应该也是可行的。

花一个小时阅读了MDN Web协议,写就了HttpClient发送文件的实例, 看官自取。

02

头脑风暴

      我们跟随常见的表单上传文件思路来实现HttpClinet上传文件。

multipart/form-data是一种由多部分表单域值组成的媒体类型,每部分由边界线(一个由'--'开始的字符串)划分。

如下面的表单, 有三个待提交input表单字段


<form action="http://localhost:8000/" method="post" enctype="multipart/form-data">
  <input type="text" name="myTextField">
  <input type="checkbox" name="myCheckBox">Check</input>
  <input type="file" name="myFile">
  <button>Send the file</button>
</form>

选中文件,点击[Send the file]按钮,提交表单,会发出如下请求

请观察由boundary划分的每个表单域和值, 其中myFile是一个文件表单域, 这个文件域需要单独指定Content-Type类型。

03

照葫芦画瓢

       以上就是常规的Html表单上传文件的协议分析,回到本文主题, 这次会使用HttpClient编码形式发送只含有一个文件表单域的请求 (依旧利用的multipart/form-data媒体类型), 这也是下文的实现思路。

下面是httpclient向localhost:5000/upload地址上传文件, 服务器返回图片的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. 准备文件表单域和值
                var byteArrayContent = new ByteArrayContent(bytes);
                byteArrayContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/png");

                // 2.  向MultipartFormDataContent插入准备好的文件表单域值, 注意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发送文件。•文件表单域值:  byteArrayContent, "uploadedFile", "\\"001ggg.png\\"" 中的参数2: 字段名称很重要,要与下面服务端的参数名匹配。

3.2 服务端

上传文件的代码在《ABP小试牛刀之上传文件》一文已经体现,本次截取接收文件上传的核心代码

[Consumes("multipart/form-data")]
[Route("upload")]
[ProducesResponseType(typeof(Guid), 200)]
[HttpPost]
public async Task<string> 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;

码甲哥从不打诳语,启动客户端/服务端

3.3 授人以渔

成熟的技术必须有成熟的调试和监测手段!

成熟的技术必须有成熟的调试和监测手段!

成熟的技术必须有成熟的调试和监测手段!

每当做web开发出现阻塞的时候,我就掏出web利器Fiddler,跟着Fiddler去策马奔腾吧。

# 全文总结

1.对常规html表单上传文件的功能,做协议级分析。2.根据分析结果,HttpClient使用同样的姿势发送文件: 使用multipart/form-data(多部分表单媒体类型)发起上传请求。

[1] 媒体类型MIME: https://developer.mozilla.org/zhCN/docs/Web/HTTP/Basics_of_HTTP/MIME_types

我是有态度的马甲,不追热点,原创输出 # 八股文 # 硬核干货 # 职场心得 #,欢迎关注。

点分享

点点赞

点在看

以上是关于童鞋,[HttpClient发送文件的技术实践]请查收的主要内容,如果未能解决你的问题,请参考以下文章

使用 HttpClient,发送没有架构的授权令牌

HttpClient发送POST请求

如何在 C# 中使用 HttpClient 发送文件和表单数据

使用 HttpClient 向本地 json 文件发送 POST 请求

httpclient工具类,post请求发送json字符串参数,中文乱码处理

测试框架HttpClient