How to avoid duplicate content headers using MVC3 FileContentResult?

We have several files stored in sql database. In the ASP.NET MVC3 form, we show 2 links:

View this file | Download this file

These links refer to these respective action methods. The download works as expected - clicking on the link makes the save dialog in the browser. However, a duplicate of the Content-Disposition headers for the browser appears on the display, resulting in an error in Chrome and a blank page in Firefox.

[ActionName("display-file")] public virtual ActionResult DisplayFile (Guid fileId, string fileName) { var file = _repos.GetFileInfo(fileId); if (file != null) { Response.AddHeader("Content-Disposition", string.Format("inline; filename={0}", file.Name)); return File(file.Content, file.MimeType, file.Name); } } [ActionName("download-file")] public virtual ActionResult DownloadFile (Guid fileId, string fileName) { var file = _repos.GetFileInfo(fileId); if (file != null) { return File(file.Content, file.MimeType, file.Name); } } 

Here are two headers sent to the browser for the display action:

 Content-Disposition: inline; filename=name-of-my-file.pdf Content-Disposition: attachment; filename="name-of-my-file.pdf" 

I tried changing my custom content header to wrap the file name in double quotes, but it still sent 2 headers to the browser. I also tried removing the Content-Disposition header before adding the custom one, but it appears when the attachment header is added after the FileContentResult returns.

This code worked. Yesterday I checked the test and noticed that it no longer works in Chrome or Firefox. This may be due to browser updates. IE8 and Safari still open the file correctly.

Update

Thanks again Darin, you're right. We actually used this approach because of another question that you answered .

A bit more information on how this was ultimately resolved on our part, we have a custom route for linking to the display file:

 context.MapRoute(null, "path/to/display-file-attachment/{fileId}/{fileName}", new { area = "AreaName", controller = "ControllerName", action = "DisplayFile", } ); 

The hyperlink on the page passes the file name to the action method via the route parameter, so it is already part of the URL. Thus, we did not need to add a custom content header so that the file name coincided with the system when the user decided to download it (by clicking the save icon in the PDF Viewer browser). So we just used this:

 [ActionName("display-file")] public virtual ActionResult DisplayFile (Guid fileId, string fileName) { var file = _repos.GetFileInfo(fileId); if (file != null) { // no custom content-disposition header, and no 3rd fileName argument return File(file.Content, file.MimeType); } } 
+10
asp.net-mvc-3 download content-disposition
Dec 23 '11 at 1:33 pm
source share
1 answer

When using File(byte[] contents, string mimeType, string fileName) overload File(byte[] contents, string mimeType, string fileName) Content-Disposition header is automatically added to the response using attachment , so you do not need to add it a second time. For inline you can use the following File(byte[] contents, string mimeType) overload File(byte[] contents, string mimeType) and manually add the Content-Disposition header:

 [ActionName("display-file")] public virtual ActionResult DisplayFile(Guid fileId) { var file = _repos.GetFileInfo(fileId); var cd = new ContentDisposition { Inline = true, FileName = file.Name }; Response.AddHeader("Content-Disposition", cd.ToString()); return File(file.Content, file.MimeType); } [ActionName("download-file")] public virtual ActionResult DownloadFile(Guid fileId) { var file = _repos.GetFileInfo(fileId); return File(file.Content, file.MimeType, file.Name); } 
+24
Dec 23 '11 at 1:48
source share
— -



All Articles