在ASP MVC 3中创建可下载的文本文件时无法访问关闭的流
我试图提示可下载的文本文件(.txt),但我收到此错误:
无法访问封闭的Stream。
我在这里看过类似的问题: 无法访问封闭的流但是它不是很有用。
这是我的代码:
private FileStreamResult Export() { string name = "filename.txt"; MemoryStream stream = new MemoryStream(); using (StreamWriter writer = new StreamWriter(stream)) { StringBuilder sb = new StringBuilder(); sb.Append("A text..."); writer.WriteLine(sb.ToString()); } return File(stream, "text/plain", name); }
更新(工作副本):
这给了我一个空白的文本文件。
private FileResult Export() { string name = "filename.txt"; MemoryStream stream = new MemoryStream(); StreamWriter writer = new StreamWriter(stream); StringBuilder sb = new StringBuilder(); sb.Append("A text..."); writer.WriteLine(sb.ToString()); writer.Flush(); stream.Seek(0, SeekOrigin.Begin); return File(stream, "text/plain", name); }
这是正确的,当你将流包装在另一个流中时,在它们中的任何一个上调用.Close()
或.Dispose()
将处理整个流。 在这种情况下,将MemoryStream
包装在StreamWriter
意味着当using
语句完成时, StreamWriter
和MemoryStream
都被StreamWriter
。
我的猜测是,因为你正在返回一个FileStreamResult
,封装File
将在不再使用流后为你关闭流。 在这种情况下,您不想使用using
语句,并且希望在返回时保持流打开。
UPDATE
由于流是前向访问,因此您需要将流返回到开头以允许读取数据。
stream.Seek(0, SeekOrigin.Begin);
只需删除那个using
语句 – 你将被处置的对象引用传递给File
方法,这就是你得到exception的原因。 来自MSDN ,
调用StreamWriter.Dispose时,StreamWriter对象在提供的Stream对象上调用Dispose。
我相信File
会在使用后自行配置流(未通过查看源代码validation)。
更新:
writer.Flush();
在return语句之前应该帮助你
在FileStreamResult中使用它之前,必须将memorystream的位置设置为0,否则将从当前位置(IE结束流)读取。
stream.Position = 0; return File(stream, "text/plain", name);
刚刚有同样的事情。
我知道这个线程很古老,只是希望能帮助其他人解决同样的问题。
使用FileResult
替换操作中的FileStreamResult
类型。
- global.asax和global.asax.cs之间有什么区别
- MVC中的会话管理
- 如何在WebForms项目中启用MVC?
- Resolve ()是否按会话返回对象?
- MVC 6 Tag Helpers Intellisense?
- 如何使用Kendo UI Grid与ToDataSourceResult(),IQueryable ,ViewModel和AutoMapper?
- entity framework在Web api / MVC中使用异步控制器进行处理
- 如何在ViewModel中使用数组?
- MVC相当于Webforms“UrlAuthorizationModule.CheckUrlAccessForPrincipal”