Come posso presentare un file per il download da un controller MVC?

In WebForms, normalmente avrei un codice come questo per consentire al browser di presentare un popup “Download File” con un tipo di file arbitrario, come un PDF e un nome file:

Response.Clear() Response.ClearHeaders() ''# Send the file to the output stream Response.Buffer = True Response.AddHeader("Content-Length", pdfData.Length.ToString()) Response.AddHeader("Content-Disposition", "attachment; filename= " & Server.HtmlEncode(filename)) ''# Set the output stream to the correct content type (PDF). Response.ContentType = "application/pdf" ''# Output the file Response.BinaryWrite(pdfData) ''# Flushing the Response to display the serialized data ''# to the client browser. Response.Flush() Response.End() 

Come faccio a svolgere la stessa attività in ASP.NET MVC?

Restituisci un FileResult o FileStreamResult dalla tua azione, a seconda che il file esista o lo crei al volo.

 public ActionResult GetPdf(string filename) { return File(filename, "application/pdf", Server.UrlEncode(filename)); } 

Per forzare il download di un file PDF, anziché essere gestito dal plug-in PDF del browser:

 public ActionResult DownloadPDF() { return File("~/Content/MyFile.pdf", "application/pdf", "MyRenamedFile.pdf"); } 

Se si desidera consentire al browser di gestire il comportamento predefinito (plug-in o download), è sufficiente inviare due parametri.

 public ActionResult DownloadPDF() { return File("~/Content/MyFile.pdf", "application/pdf"); } 

Dovrai utilizzare il terzo parametro per specificare un nome per il file nella finestra di dialogo del browser.

AGGIORNAMENTO: Charlino ha ragione quando si passa il terzo parametro (download filename) Content-Disposition: attachment; viene aggiunto all’Http Response Header. La mia soluzione era inviare l’ application\force-download come mime-type, ma questo genera un problema con il nome del file del download, quindi il terzo parametro è necessario per inviare un buon nome file, eliminando quindi la necessità di forzare un download .

Puoi fare lo stesso in Razor o nel controller, in questo modo ..

 @{ //do this on the top most of your View, immediately after `using` statement Response.ContentType = "application/pdf"; Response.AddHeader("Content-Disposition", "attachment; filename=receipt.pdf"); } 

O nel controller ..

 public ActionResult Receipt() { Response.ContentType = "application/pdf"; Response.AddHeader("Content-Disposition", "attachment; filename=receipt.pdf"); return View(); } 

Ho provato questo in Chrome e IE9, entrambi stanno scaricando il file pdf.

Probabilmente dovrei aggiungere Sto usando RazorPDF per generare i miei PDF. Ecco un blog a riguardo: http://nyveldt.com/blog/post/Introducing-RazorPDF

Si dovrebbe guardare il metodo File del controller. Questo è esattamente ciò che è per. Restituisce un FilePathResult invece di un ActionResult.

mgnoonan,

Puoi farlo per restituire un FileStream:

 ///  /// Creates a new Excel spreadsheet based on a template using the NPOI library. /// The template is changed in memory and a copy of it is sent to /// the user computer through a file stream. ///  /// Excel report [AcceptVerbs(HttpVerbs.Post)] public ActionResult NPOICreate() { try { // Opening the Excel template... FileStream fs = new FileStream(Server.MapPath(@"\Content\NPOITemplate.xls"), FileMode.Open, FileAccess.Read); // Getting the complete workbook... HSSFWorkbook templateWorkbook = new HSSFWorkbook(fs, true); // Getting the worksheet by its name... HSSFSheet sheet = templateWorkbook.GetSheet("Sheet1"); // Getting the row... 0 is the first row. HSSFRow dataRow = sheet.GetRow(4); // Setting the value 77 at row 5 column 1 dataRow.GetCell(0).SetCellValue(77); // Forcing formula recalculation... sheet.ForceFormulaRecalculation = true; MemoryStream ms = new MemoryStream(); // Writing the workbook content to the FileStream... templateWorkbook.Write(ms); TempData["Message"] = "Excel report created successfully!"; // Sending the server processed data back to the user computer... return File(ms.ToArray(), "application/vnd.ms-excel", "NPOINewFile.xls"); } catch(Exception ex) { TempData["Message"] = "Oops! Something went wrong."; return RedirectToAction("NPOI"); } } 

Usa il tipo di file .ashx e usa lo stesso codice