2011-08-23 100 views
8

我正在使用MVC 3我想动态创建一个CSV文件供下载,但我不确定正确的MVC方向。使用响应流的MVC控制器

在传统的ASP.net,我会写这样的:

Response.ClearHeaders(); 
Response.ContentType = "text/csv"; 
Response.AddHeader("content-disposition", attachment;filename='Test.csv'"); 
Response.Write("1,2,3"); 
Response.End(); 

我已经看了看ContentResult类型行动,但看来我需要创建的结果作为一个字符串,即

return Content(myData,“text/csv”);

我可以,我想,建立一个字符串,但由于这些文件可能是几千行,对我来说这似乎效率低下。

难道有人指着我正确的方向吗?谢谢。

+0

创建一个自定义的ActionResult类型,详见本文:[http://stackoverflow.com/questions/989927/recommended-way-to-create-an-actionresult-with-a-file-extension?rq=1] [1] [1]:http://stackoverflow.com/questions/989927/recommended-way-to-create-an-actionresult-with-a-file-extension?rq=1 –

+0

看起来确实是http:///stackoverflow.com/q/943122/1178314其中有一个相当不错的答案imho(http://stackoverflow.com/a/13456219/1178314) –

回答

5

我昨天花了类似的问题了一段时间,这里是如何做到这一点正确的做法:

public ActionResult CreateReport() 
{ 
    var reportData = MyGetDataFunction(); 
    var serverPipe = new AnonymousPipeServerStream(PipeDirection.Out); 
    Task.Run(() => 
    { 
     using (serverPipe) 
     { 
      MyWriteDataToFile(reportData, serverPipe) 
     } 
    }); 

    var clientPipe = new AnonymousPipeClientStream(PipeDirection.In, 
      serverPipe.ClientSafePipeHandle); 
    return new FileStreamResult(clientPipe, "text/csv"); 
} 
+0

你确定使用(serverPipe)?它将在FileStreamResult(clientPipe)中使用,如果任务运行很快,会发生什么情况? – Slava

+0

@Slava系统将管理管道两端之间的数据流,因此不应该担心,它不会让任务关闭服务器管道,直到它能够消耗所有的数据,换句话说,任务不会突然退出,它将在写入或关闭时保存,试试吧,它可以工作。 – galets

3
+0

我目前使用类似的文件(Encoding.UTF8.GetBytes(sb .ToString()),“text/csv”,fileName),但它仍然是一个潜在的问题,在提交视图/响应之前在内存中构建整个输出。 – Neilski

+0

调查File()的其他重载。请看看我发布的链接。一些重载不要求您在内存中构建文件。 –

+0

在将文件提交到File ActionResult之前,是不是正在构建一个字节数组(byte []),它仍然在内存中完成输出数据?例如:return File(imageData,“image/jpeg”,“fileName.jpg”); – Neilski

13

我已经找到一个可能的解决这个问题。您可以简单地定义action方法以返回EmptyResult()并直接写入响应流。例如:

public ActionResult RobotsText() { 
    Response.ContentType = "text/plain"; 
    Response.Write("User-agent: *\r\nAllow: /"); 
    return new EmptyResult(); 
} 

这似乎没有任何问题。不知道“MVC”它是如何......

+0

这是一个黑客,MVC控制器不应该直接写入响应流。这应该是操作结果对象的ExecuteResult方法的工作。 –

-1

尝试是这样的:

public ActionResult CreateReport(string report, string writer) 
{ 
    var stream = new MemoryStream(); 
    var streamWriter = new StreamWriter(stream); 

    _generateReport.GenerateReport(report, writer); 

    streamWriter.Flush(); 
    stream.Seek(0, SeekOrigin.Begin); 

    return new FileStreamResult(stream, writer.MimeType); 
} 
+1

这完全破坏了Streams的目的。请不要在生产代码中执行此操作。 – makhdumi