What's the difference between the four File Results in ASP.NET MVC

asp.net MvcFileResulttype

asp.net Mvc Problem Overview


ASP.NET has four different types of file results:

  • FileContentResult: Sends the contents of a binary file to the response.
  • FilePathResult: Sends the contents of a file to the response
  • FileResult: Returns binary output to write to the response
  • FileStreamResult: Sends binary content to the response by using a Stream instance

Those descriptions are take from MSDN and with the exception of the FileStreamResult the first three sound identical. So what is the difference between them?

asp.net Mvc Solutions


Solution 1 - asp.net Mvc

FileResult is an abstract base class for all the others.

  • FileContentResult - you use it when you have a byte array you would like to return as a file
  • FilePathResult - when you have a file on disk and would like to return its content (you give a path)
  • FileStreamResult - you have a stream open, you want to return its content as a file

However, you'll rarely have to use these classes - you can just use one of Controller.File overloads and let ASP.NET MVC do the magic for you.

Solution 2 - asp.net Mvc

Great question...and deserves more details. I find myself here as a result of an interesting situation. We were delivering some pdf attachments via the MVC3/C# environment. Our code got released and we started getting some responses from our clients that the downloads were behaving strangely when they were using Chrome and the file type was being converted over to 'pdf-, attachment.pdf-, attachment'. Yup...you got it...the whole thing. So, one could rewrite it to just be 'pdf' and the file would still save intact, but what a mess!

So, to describe the initial situation, we were setting the 'Content-Disposition' header then returning a FileContentResult...

var cd = new System.Net.Mime.ContentDisposition
            {
                FileName = result.Attachment.FileName,
                Inline = false
            };
            Response.AppendHeader("Content-Disposition", cd.ToString());

return File(result.Attachment.Data, MimeExtensionHelper.GetMimeType(result.Attachment.FileName), result.Attachment.FileName);

Seemed good. Worked fine in IE. So I did some research and tried implementing FileStreamResult instead (keeping the Content-Disposition setter):

MemoryStream dataStream = new MemoryStream();
dataStream.Write(result.Attachment.Data, 0, result.Attachment.Data.Length);
dataStream.Position = 0;
return new FileStreamResult(dataStream, MimeExtensionHelper.GetMimeType(result.Attachment.FileName));

It fixed the issue in Chrome! Hmmm...but why in the heck should I have to take my perfectly good byte array and stream it and then return it via this to get the file name to work right?

Then came the Fiddler.

With FileContentResult, I got 2 Content-Dispositions in the header. With FileStreamResult, I got 1.

FileContentResult appends a Content-Disposition header when providing the File Name and Chrome considers multiples of this header as an error.

Odd reaction...but definitely one that's good to know.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRobert MacLeanView Question on Stackoverflow
Solution 1 - asp.net MvcmaciejkowView Answer on Stackoverflow
Solution 2 - asp.net MvcbeauXjamesView Answer on Stackoverflow