我有一个声明如下的控制器动作:
[Authorize(Order = 0, Roles = "Requester,Controller,Installer")]
public FileStreamResult ExportJobCards()
此方法的主体构建CSV行的集合,并尝试将它们作为文件返回,如下所示:
using (var sw = new StreamWriter(new MemoryStream()))
{
foreach (var line in lines)
{
sw.WriteLine(line);
}
return new FileStreamResult(sw.BaseStream, "text/csv");
}
当我使用以下操作链接请求此操作时...
Html.ActionLink("Export to Excel", "ExportJobCards")
...导出方法正确执行,即上述代码中的lines
集合中存在所有必需的CSV数据,但我收到未找到文件错误最终的结果。
修改
与Tommy观察一致,我将return
移出using
,我现在得到一个文件,但文件是空的。实际生成一个空的文件的新代码是:
var sw = new StreamWriter(new MemoryStream());
foreach (var line in lines)
{
sw.WriteLine(line);
}
sw.Flush();
return new FileStreamResult(sw.BaseStream, "text/csv");
答案 0 :(得分:2)
使用当前设置,Using语句在返回完成之前处理StringWriter,这会导致找不到null引用/文件错误。在退出之前删除using语句或将StringWriter设置为另一个变量,你应该继续摆脱File Not Found错误。
现在考虑你的第二个问题,将内存流作为文件流结果查看,你可能需要改变你的回报
sw.BaseStream.seek(0, SeekOrigin.Begin)
return new FileStreamResult(sw.BaseStream, "text/csv");
因为当你返回时指针仍然在流的末尾。
答案 1 :(得分:0)
它会抛出该错误,因为您没有给它一个文件流。你想要的是FileContentResult,你可以传递任意内容。此内容必须是您内容的字节数组,可能最容易:
因为你必须编写这段代码,最简单的方法是创建一个新的FileStringResult,它继承自可以接受字符串或字符串构建器的基础FileResult。覆盖WriteFile(HttpResponseBase响应)以执行字符串到byte []的转换并将其推送到响应中。看看MVC源代码中的FileStreamResult类,它非常小而且容易做到。