其实公司网站asp源码分享下载的问题并不复杂,但是又很多的朋友都不太了解网站制作公司网站源码,因此呢,今天小编就来为大家分享公司网站asp源码分享下载的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!
最近要使用ASP.NETCOREWEBAPI用来下载文件,使用的.NETCORE3.1。考虑如下场景:
文件是程序生成的。文件应该能兼容各种格式。浏览器可以感知进行下载。
准备
经过简单的调研,得到以下结论。
ASP.NETCORE提供FileResult这种类型的ActionResult,可以直接返回文件结果,不需要直接处理HttpResponse。通过Stream可以直接返回文件流供浏览器下载。FileStreamResult是FileResult的具体实现,返回值应该是此类对象。Stream有多种类型,适合直接内存中生成文件对象的是MemoryStream。对目标有了基础的了解,就可以开始动手实现了。
实现
建立好ASP.NETCOREWEBAPI工程,把生成文件的代码独立出来一个函数。我这里需要是下载一个CSV格式的文件,因此生成一个CSV文件。对于磁盘上的文件,可以使用FileStream对象,由于我这里需要运行中生成这个文件,需要使用MemoryStream。
usingvarstream=newMemoryStream();\nusingvarwriter=newStreamWriter(stream);\n//生成标题\nvarpropCollection=ttype.GetProperties();\nforeach(varninpropCollection)\n{\nwriter.Write(n.Name);\nwriter.Write(&34;);\n}\nwriter.WriteLine();\n//生成内容\nforeach(variteminres)\n{\nforeach(varninpropCollection)\n{\nwriter.Write(Convert.ToString(n.GetValue(item)));\nwriter.Write(&34;);\n}\nwriter.WriteLine();\n}\n
请不要考虑里面反射的相关内容,按照自己的逻辑生成CSV即可,我只是懒得改代码而已。代码中使用到了一些新的语法特性,请注意对低版本的.NET不一定适用。直接返回Stream对象给Controller处理,处理代码如下:
varres=awaitinfo.GetAllQueryResult();\nvaractionresult=newFileStreamResult(res,newMicrosoft.Net.Http.Headers.MediaTypeHeaderValue(&34;));\nreturnactionresult;\n
CSV的Content-Type是text/csv,如果下载别的文件,请自行查询MIME格式。
调试
直接执行上面的代码,直接报错“无法读取已经关闭的流”。猜测是离开using语句块的时候,stream自动被关闭了。改动很简单,去掉using语句,不再报相同错误。
但是返回的文件长度一直是0,单步调试发现Writer执行完毕之后,stream返回的长度是0,内容实际上并没有写入,想起有一个Flush(),可以添加以确保数据写入。
单步显示stream长度有了,但是返回的长度还是0。继续单步调试发现Stream的Postion是停在文件结尾的,这个和直接开始读取文件完全不一样,文件读取一般是从开头开始的,于是直接设置Postion为0,问题解决。
下载能够成功了,但是文件名一直显示的是随机生成的,体验很差。设置一下FileDownloadName即可。
核心代码如下:
publicasyncTask<Stream>GetAllQueryResult()\n{\nvarstream=newMemoryStream();\nvarwriter=newStreamWriter(stream);\n//生成标题\nvarpropCollection=ttype.GetProperties();\nforeach(varninpropCollection)\n{\nwriter.Write(n.Name);\nwriter.Write(&34;);\n}\nwriter.WriteLine();\n//生成内容\nforeach(variteminres)\n{\nforeach(varninpropCollection)\n{\nwriter.Write(Convert.ToString(n.GetValue(item)));\nwriter.Write(&34;);\n}\nwriter.WriteLine();\n}\nwriter.Flush();\nstream.Position=0;\nreturnstream;\n}\n
[HttpPost(&34;)]\n[ProducesResponseType(typeof(FileResult),Status200OK)]\npublicasyncTask<FileResult>Download()\n{\nvarinfo=newInfo();\nvarres=awaitinfo.GetAllQueryResult();\n\nvaractionresult=newFileStreamResult(res,newMicrosoft.Net.Http.Headers.MediaTypeHeaderValue(&34;));\nactionresult.FileDownloadName=&34;;\n//Response.ContentLength=res.Length;\nreturnactionresult;\n}\n
使用swagger调用,最后效果:
总结
后来查了一些资料,总结了一下:
MemoryStream如果使用using语句,会在离开代码块的时候自动关闭,实际上ASP.NETCORE会自动处理关闭的事项,不需要使用using语句。由于生成文件的过程是从文件流的开头一直进行到末尾的,因此向请求端返回结果时,应当重置Stream的游标,从0开始传输。记得在使用writer之后使用Flush()以确保数据有写入。如果不确定文件格式,可以直接返回MIME值为application/oct-stream。设置FileStreamResult的FileDownloadName属性可以修改文件的默认名称。(可选)可以通过设置Response.ContentLength来设置文件的长度。
公司网站asp源码分享下载的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于网站制作公司网站源码、公司网站asp源码分享下载的信息别忘了在本站进行查找哦。
