¿Cómo devolver PDF al navegador en MVC?

Tengo este código de demostración para iTextSharp

Document document = new Document(); try { PdfWriter.GetInstance(document, new FileStream("Chap0101.pdf", FileMode.Create)); document.Open(); document.Add(new Paragraph("Hello World")); } catch (DocumentException de) { Console.Error.WriteLine(de.Message); } catch (IOException ioe) { Console.Error.WriteLine(ioe.Message); } document.Close(); 

¿Cómo hago para que el controlador devuelva el documento pdf al navegador?

EDITAR:

Al ejecutar este código, se abre Acrobat pero aparece un mensaje de error “El archivo está dañado y no se pudo reparar”.

  public FileStreamResult pdf() { MemoryStream m = new MemoryStream(); Document document = new Document(); PdfWriter.GetInstance(document, m); document.Open(); document.Add(new Paragraph("Hello World")); document.Add(new Paragraph(DateTime.Now.ToString())); m.Position = 0; return File(m, "application/pdf"); } 

¿Alguna idea de por qué esto no funciona?

Devuelve un FileContentResult . La última línea en su acción de controlador sería algo así como:

 return File("Chap0101.pdf", "application/pdf"); 

Si está generando este PDF dinámicamente, puede ser mejor utilizar un MemoryStream y crear el documento en la memoria en lugar de guardarlo en un archivo. El código sería algo así como:

 Document document = new Document(); MemoryStream stream = new MemoryStream(); try { PdfWriter pdfWriter = PdfWriter.GetInstance(document, stream); pdfWriter.CloseStream = false; document.Open(); document.Add(new Paragraph("Hello World")); } catch (DocumentException de) { Console.Error.WriteLine(de.Message); } catch (IOException ioe) { Console.Error.WriteLine(ioe.Message); } document.Close(); stream.Flush(); //Always catches me out stream.Position = 0; //Not sure if this is required return File(stream, "application/pdf", "DownloadName.pdf"); 

Lo tengo trabajando con este código.

 using iTextSharp.text; using iTextSharp.text.pdf; public FileStreamResult pdf() { MemoryStream workStream = new MemoryStream(); Document document = new Document(); PdfWriter.GetInstance(document, workStream).CloseStream = false; document.Open(); document.Add(new Paragraph("Hello World")); document.Add(new Paragraph(DateTime.Now.ToString())); document.Close(); byte[] byteInfo = workStream.ToArray(); workStream.Write(byteInfo, 0, byteInfo.Length); workStream.Position = 0; return new FileStreamResult(workStream, "application/pdf"); } 

Debes especificar:

 Response.AppendHeader("content-disposition", "inline; filename=file.pdf"); return new FileStreamResult(stream, "application/pdf") 

Para que el archivo se abra directamente en el navegador en lugar de descargarse

Si devuelve un FileResult de su método de acción y utiliza el método de extensión File() en el controlador, hacer lo que quiera es bastante fácil. Hay modificaciones en el método File() que tomarán los contenidos binarios del archivo, la ruta al archivo o un Stream .

 public FileResult DownloadFile() { return File("path\\to\\pdf.pdf", "application/pdf"); } 

Me encontré con problemas similares y me encontré con una solución. Utilicé dos publicaciones, una de la stack que muestra el método para volver a descargar y otra que muestra una solución de trabajo para ItextSharp y MVC.

 public FileStreamResult About() { // Set up the document and the MS to write it to and create the PDF writer instance MemoryStream ms = new MemoryStream(); Document document = new Document(PageSize.A4.Rotate()); PdfWriter writer = PdfWriter.GetInstance(document, ms); // Open the PDF document document.Open(); // Set up fonts used in the document Font font_heading_1 = FontFactory.GetFont(FontFactory.TIMES_ROMAN, 19, Font.BOLD); Font font_body = FontFactory.GetFont(FontFactory.TIMES_ROMAN, 9); // Create the heading paragraph with the headig font Paragraph paragraph; paragraph = new Paragraph("Hello world!", font_heading_1); // Add a horizontal line below the headig text and add it to the paragraph iTextSharp.text.pdf.draw.VerticalPositionMark seperator = new iTextSharp.text.pdf.draw.LineSeparator(); seperator.Offset = -6f; paragraph.Add(seperator); // Add paragraph to document document.Add(paragraph); // Close the PDF document document.Close(); // Hat tip to David for his code on stackoverflow for this bit // https://stackoverflow.com/questions/779430/asp-net-mvc-how-to-get-view-to-generate-pdf byte[] file = ms.ToArray(); MemoryStream output = new MemoryStream(); output.Write(file, 0, file.Length); output.Position = 0; HttpContext.Response.AddHeader("content-disposition","attachment; filename=form.pdf"); // Return the output stream return File(output, "application/pdf"); //new FileStreamResult(output, "application/pdf"); } 

Puede crear una clase personalizada para modificar el tipo de contenido y agregar el archivo a la respuesta.

http://haacked.com/archive/2008/05/10/writing-a-custom-file-download-action-result-for-asp.net-mvc.aspx

Sé que esta pregunta es antigua, pero pensé que podría compartir esto ya que no pude encontrar nada similar.

Quería crear mis vistas / modelos de forma normal usando Razor y hacer que se renderizaran como Pdfs .

De esta forma, tuve control sobre la presentación de PDF utilizando la salida html estándar en lugar de averiguar cómo diseñar el documento usando iTextSharp.

El proyecto y el código fuente están disponibles aquí con las instrucciones de instalación de nuget:

https://github.com/andyhutch77/MvcRazorToPdf

 Install-Package MvcRazorToPdf 

Normalmente haría un Response.Flush seguido de un Response.Close, pero por alguna razón a la biblioteca iTextSharp no parece gustarle esto. Los datos no pasan y Adobe piensa que el PDF está dañado. Deje fuera la función Response.Close y vea si sus resultados son mejores:

 Response.Clear(); Response.ContentType = "application/pdf"; Response.AppendHeader("Content-disposition", "attachment; filename=file.pdf"); // open in a new window Response.OutputStream.Write(outStream.GetBuffer(), 0, outStream.GetBuffer().Length); Response.Flush(); // For some reason, if we close the Response stream, the PDF doesn't make it through //Response.Close(); 

si devuelve datos binarios de DB para mostrar PDF en ventana emergente o navegador, siga este código: –

Ver pagina:

 @using (Html.BeginForm("DisplayPDF", "Scan", FormMethod.Post)) { View PDF } 

Controlador de escaneo:

 public ActionResult DisplayPDF() { byte[] byteArray = GetPdfFromDB(4); MemoryStream pdfStream = new MemoryStream(); pdfStream.Write(byteArray, 0, byteArray.Length); pdfStream.Position = 0; return new FileStreamResult(pdfStream, "application/pdf"); } private byte[] GetPdfFromDB(int id) { #region byte[] bytes = { }; string constr = System.Configuration.ConfigurationManager.ConnectionStrings["Connection"].ConnectionString; using (SqlConnection con = new SqlConnection(constr)) { using (SqlCommand cmd = new SqlCommand()) { cmd.CommandText = "SELECT Scan_Pdf_File FROM PWF_InvoiceMain WHERE InvoiceID=@Id and Enabled = 1"; cmd.Parameters.AddWithValue("@Id", id); cmd.Connection = con; con.Open(); using (SqlDataReader sdr = cmd.ExecuteReader()) { if (sdr.HasRows == true) { sdr.Read(); bytes = (byte[])sdr["Scan_Pdf_File"]; } } con.Close(); } } return bytes; #endregion } 
 HttpContext.Response.AddHeader("content-disposition","attachment; filename=form.pdf"); 

si el nombre del archivo está generando dinámicamente, entonces cómo definir el nombre del archivo aquí, está generando a través de GUID aquí.