俄语在线翻译,全国在职研究生考试,何者为卿狂txt
最近要使用asp.net core webapi用来下载文件,使用的.net core 3.1。考虑如下场景:
经过简单的调研,得到以下结论。
建立好asp.net core webapi工程,把生成文件的代码独立出来一个函数。我这里需要是下载一个csv格式的文件,因此生成一个csv文件。
对于磁盘上的文件,可以使用filestream对象,由于我这里需要运行中生成这个文件,需要使用memorystream。
using var stream = new memorystream(); using var writer = new streamwriter(stream); //生成标题 var propcollection = ttype.getproperties(); foreach (var n in propcollection) { writer.write(n.name); writer.write(","); } writer.writeline(); //生成内容 foreach (var item in res) { foreach (var n in propcollection) { writer.write(convert.tostring(n.getvalue(item))); writer.write(","); } writer.writeline(); }
- 请不要考虑里面反射的相关内容,按照自己的逻辑生成csv即可,我只是懒得改代码而已。
- 代码中使用到了一些新的语法特性,请注意对低版本的.net不一定适用。
直接返回stream对象给controller处理,处理代码如下:
var res = await info.getallqueryresult(); var actionresult = new filestreamresult(res, new microsoft.net.http.headers.mediatypeheadervalue("text/csv")); return actionresult;
csv的content-type是text/csv,如果下载别的文件,请自行查询mime格式。
直接执行上面的代码,直接报错“无法读取已经关闭的流”。猜测是离开using语句块的时候,stream自动被关闭了。改动很简单,去掉using语句,不再报相同错误。
但是返回的文件长度一直是0,单步调试发现writer执行完毕之后,stream返回的长度是0,内容实际上并没有写入,想起有一个flush(),可以添加以确保数据写入。
单步显示stream长度有了,但是返回的长度还是0。继续单步调试发现stream的postion是停在文件结尾的,这个和直接开始读取文件完全不一样,文件读取一般是从开头开始的,于是直接设置postion为0,问题解决。
下载能够成功了,但是文件名一直显示的是随机生成的,体验很差。设置一下filedownloadname即可。
核心代码如下:
public async task<stream> getallqueryresult() { var stream = new memorystream(); var writer = new streamwriter(stream); //生成标题 var propcollection = ttype.getproperties(); foreach (var n in propcollection) { writer.write(n.name); writer.write(","); } writer.writeline(); //生成内容 foreach (var item in res) { foreach (var n in propcollection) { writer.write(convert.tostring(n.getvalue(item))); writer.write(","); } writer.writeline(); } writer.flush(); stream.position = 0; return stream; }
[httppost("file")] [producesresponsetype(typeof(fileresult), status200ok)] public async task<fileresult> download() { var info = new info(); var res = await info.getallqueryresult(); var actionresult = new filestreamresult(res, new microsoft.net.http.headers.mediatypeheadervalue("text/csv")); actionresult.filedownloadname = "carinfos.csv"; //response.contentlength = res.length; return actionresult; }
使用swagger调用,最后效果:
后来查了一些资料,总结了一下:
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Blazor server side 自家的一些开源的, 实用型项目的进度之 CEF客户端
.NET IoC模式依赖反转(DIP)、控制反转(Ioc)、依赖注入(DI)
vue+.netcore可支持业务代码扩展的开发框架 VOL.Vue 2.0版本发布
网友评论