MVC Controller Using Response Stream

2019-01-24 09:34发布

问题:

I'm using MVC 3 I would like to dynamically create a CSV file for download, but I am unsure as to the correct MVC orientated approach.

In conventional ASP.net, I would have written something like:

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

I have looked at the ContentResult action but it appears that I would need to create the result as a string, i.e.

return Content(myData, "text/csv");

I could, I suppose, build a string, but since these files could be several thousand lines long, this seems inefficient to me.

Could someone point me in the right direction? Thanks.

回答1:

I spent some time on the similar problem yesterday, and here's how to do it right way:

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


回答2:

I have found one possible solution to this problem. You can simply define the action method to return an EmptyResult() and write directly to the response stream. For example:

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

This seems to work without any problems. Not sure how 'MVC' it is...



回答3:

Try returning one the FileResults: http://msdn.microsoft.com/en-us/library/system.web.mvc.fileresult.aspx

Also see this example: http://forums.asp.net/t/1491579.aspx/1



回答4:

Try something like this:

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);
}