FileStreamResult控制器操作发现文件未找到错误

时间:2010-08-25 13:10:54

标签: asp.net asp.net-mvc

我有一个声明如下的控制器动作:

[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");  

2 个答案:

答案 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,你可以传递任意内容。此内容必须是您内容的字节数组,可能最容易:

  1. 使用stringbuilder而不是streamwriter
  2. 从构建器中获取字符串
  3. 使用静态方法System.Text.UnicodeEncoding.Unicode.GetBytes(string)获取字节数组
  4. 将字节数组提供给FileContentResult
  5. 因为你必须编写这段代码,最简单的方法是创建一个新的FileStringResult,它继承自可以接受字符串或字符串构建器的基础FileResult。覆盖WriteFile(HttpResponseBase响应)以执行字符串到byte []的转换并将其推送到响应中。看看MVC源代码中的FileStreamResult类,它非常小而且容易做到。