Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

People also ask

What is the difference between action result and view result in MVC?

ActionResult is an abstract class, and it's base class for ViewResult class. In MVC framework, it uses ActionResult class to reference the object your action method returns. And invokes ExecuteResult method on it. And ViewResult is an implementation for this abstract class.

What differentiates the view result from another action result types?

ActionResult is an abstract or base class. On the other hand ViewResult is a subclass of ActionResult. Whenever Controller action return type is ActionResult then the action is capable of returning any subtype like view, json, RedirectToAction etc.

How many action results are there in MVC?

There are two methods in Action Result. One is ActionResult() and another one is ExecuteResult().


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.


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.