Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Download Dynamically Generated File in ASP.NET MVC

Tags:

asp.net-mvc

I need to implement a file download in ASP.NET MVC. Searching the Web, I found code like this:

public ActionResult GetFile()
{
    return File(filename, "text/csv", Server.UrlEncode(filename));
}

That's nice, but I want to create the contents of this file dynamically.

I realize I could dynamically create the file, and then use the syntax above to download that file. But wouldn't it be more efficient if I could simply write my contents directly to the response? Is this possible in MVC?

like image 440
Jonathan Wood Avatar asked May 12 '12 03:05

Jonathan Wood


2 Answers

Here's an overly simplified version of the code I ended up using. It meets my needs.

[HttpGet]
public ActionResult GetFile()
{
    Response.Clear();
    Response.AddHeader("Content-Disposition", "attachment; filename=myfile.csv");
    Response.ContentType = "text/csv";

    // Write all my data
    Response.Write(...);
    Response.End();

    // Not sure what else to do here
    return Content(String.Empty);
}
like image 138
Jonathan Wood Avatar answered Oct 25 '22 19:10

Jonathan Wood


An alternative solution is to use the overload for File() that accepts a stream.

In my case, it's a csv that I need to generate from a Controller Action, so it's a bit like this:

[HttpGet]
public ActionResult DownloadInvalidData(int fileId)
{
    string invalidDataCsv = this.importService.GetInvalidData(fileId);
    string downloadFileName = "error.csv";

    var stream = new MemoryStream();
    var writer = new StreamWriter(stream);

    writer.Write(invalidDataCsv);
    writer.Flush();
    stream.Position = 0;

    return File(stream, "text/csv", downloadFileName);
}

Note you should not dispose of the Stream or the StreamWriter before passing it to the File() function because disposing of either will close the stream making it unusable.

like image 26
kaitlinsm Avatar answered Oct 25 '22 18:10

kaitlinsm