CSV files being saved as XLS or nothing on download

2k views Asked by At

I am trying to allow a user to download a csv file, and open it with Excel (preferably with the 'Open File with Excel' option already selected).

//Cont.cs
public ActionResult CSVLink(string file)
    {
        var dir = Server.MapPath("/CSV/Stats");
        var path = Path.Combine(dir, file + ".csv"); // I have tried this both with and w/o adding the csv here, and on the anchor's href instead
        return File(path, "application/csv");
    }

//Links.cshtml
<a target="_blank" href="/CSVLink?file=Hits_20150616">Today's Hits</a>

This mostly works, as in it allows the user to download a file, but the file extension is not keeping as csv. The issue seems to be with return File(path, "application/csv");, and more specifically application/csv.

Here's a list of what happens with various mime types:

  • application/csv - The file downloads, but does not have a file extension
  • text/csv - same
  • application/binary - same
  • application/vnd.ms-excel - The file downloads as an .xls file, which messes up how it looks in Excel.

Here's another weird thing: All the files that don't have extensions, if I rename them and put the .csv on the end, they open in Excel looking perfect. This happens in both IE and Firefox (except for octet-stream, that makes it open as plain text in a new webpage).

What am I doing wrong?

1

There are 1 answers

2
David T. Macknet On

To clarify the question a wee bit: you have a file named /CSV/Stats/SomeFileName.csv and you're wanting to serve that content out to the user, correct? But I don't see where you're reading the bytes from the file, in order to serve up the content - you're serving up a file, which isn't right, unless you were to serve up a redirect to /CSV/Stats/SomeFileName.csv If you're not serving up a redirect, you'd need to do something like:

var s = File.ReadAllText(path);
return File(Encoding.Unicode.GetBytes(s.ToString()), "text/csv", file + ".csv");

Lastly: it's probably a bad thing to use file as your parameter name, there - it's at least misleading, and at worst going to cause confusion.