C#用HttpClient将文件转成流Post到另一接口

声明:原创文章,转载请注明出处。作者:易国轩

需求场景:公司需要将某报表以附件形式推送到企业微信用户。要实现此需求,包括以下步骤:

1. 用户点推送按钮,报表自动生成附件,我用的stimulreport顺利实现

2. 调用企业微信上传素材接口上传附件,获取mediaId

3. 调用消息发送接口,将mediaId对应的附件发送给指定用户

难点:我们用得比较多的方法都是通过file组件由用户选择文件后再提交,但需求场景中如果还由用户去挑选生成的附件再发送,不仅用户体验不好,也不是现实的,合理的方式是生成附件后,接口继续将文件以流的形式post到素材上传接口。所以场景需求中关键是第2点,思路有了,如何实现?竟然花费了我将近两天时间才解决。现记录下来,以供有相同需求的朋友们参考。

代码:Asp.net core3.1下采用httpclient实现

注:以下代码只是演示了将文件流post到服务端及在服务端接收流的方式,并没有去调用企业微信的素材上传接口,而是改为了在服务端另存成一个文件.

//发送端:将指定文件以流的形式post到服务端接口

        [HttpPost]

        public IActionResult UploadReport()

        {

            //以下几个变量可移为参数,直接这样写是为了方便测试

            var path = @"D:\goods.xlsx";

            var targetPath = Path.GetDirectoryName(path) + "2.xlsx";

            //接收流的接口地址 (某次我忘了加控制器Home,导致post失败)

            var url = "https://localhost:44348/Home/ReceiveFileByStream?targetPath=" + targetPath; 

            using (var client = new HttpClient())

            {

                FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read);

                var content = new StreamContent(stream);

                HttpResponseMessage response = client.PostAsync(url, content).Result;

                stream.Dispose();

                response.EnsureSuccessStatusCode();

                var res = response.Content.ReadAsStringAsync().Result;

                return Ok(new { result = res });

            }

        }

        ///

        /// 服务端接口:接收其他接口post过来的流

        /// (特别注意:接口的流并不是通过参数的形式,而是用this.HttpContext.Request.Body)

        ///

        /// 将接收到的流另存为文件

        ///

        [HttpPost]

        public async Task ReceiveFileByStream(string targetPath)

        {

            var request = this.HttpContext.Request;

            request.EnableBuffering();//确保可以多次读取

            var requestReader = new StreamReader(request.Body);

            var requestContent = requestReader.ReadToEnd();

            request.Body.Position = 0;

            if (requestContent.Length > 0)

            {

                //将收到的流存成文件

                using (var fileStream = System.IO.File.Create(targetPath))

                {

                    //如果是异步保存,则要带上await, 方法改为async

                    await requestReader.BaseStream.CopyToAsync(fileStream);

                }

                return Ok(new { result = "恭喜, 获取到了文件流,有志者事竟成" });

            }

            else

            {

                return Ok(new { result = "没有获取到文件流,不要气馁" });

            }

        }

UI端代码:

$(".btnTest3").click(() => {

            $.ajax({

                url: "/Home/UploadReport",

                type: "POST",

                data: {},

                success: res => {

                    console.log(res);

                },

                error: err => {

                    console.log(err);

                }

            })

        })

你可能感兴趣的:(C#用HttpClient将文件转成流Post到另一接口)