声明:原创文章,转载请注明出处。作者:易国轩
需求场景:公司需要将某报表以附件形式推送到企业微信用户。要实现此需求,包括以下步骤:
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 });
}
}
/// <summary>
/// 服务端接口:接收其他接口post过来的流
/// (特别注意:接口的流并不是通过参数的形式,而是用this.HttpContext.Request.Body)
/// </summary>
/// <param name=”targetPath”>将接收到的流另存为文件</param>
/// <returns></returns>
[HttpPost]
public async Task<IActionResult> 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);
}
})
})


