iTextSharp: envío de pdf en memoria en un archivo adjunto de correo electrónico

He hecho algunas preguntas aquí, pero sigo teniendo problemas. Te agradecería si pudieras decirme qué estoy haciendo mal en mi código. Ejecuto el código anterior desde una página ASP.Net y obtengo “No puedo acceder a un flujo cerrado”.

var doc = new Document(); MemoryStream memoryStream = new MemoryStream(); PdfWriter.GetInstance(doc, memoryStream); doc.Open(); doc.Add(new Paragraph("First Paragraph")); doc.Add(new Paragraph("Second Paragraph")); doc.Close(); //if I remove this line the email attachment is sent but with 0 bytes MailMessage mm = new MailMessage("username@gmail.com", "username@gmail.com") { Subject = "subject", IsBodyHtml = true, Body = "body" }; mm.Attachments.Add(new Attachment(memoryStream, "test.pdf")); SmtpClient smtp = new SmtpClient { Host = "smtp.gmail.com", Port = 587, EnableSsl = true, Credentials = new NetworkCredential("username@gmail.com", "my_password") }; smtp.Send(mm); //the "Cannot Access a Closed Stream" error is thrown here 

¡¡¡Gracias!!!

EDITAR:

Para ayudar a alguien a buscar la respuesta a esta pregunta, debajo está el código para enviar un archivo pdf adjunto a un correo electrónico sin tener que crear físicamente el archivo (gracias a Ichiban y Brianng):

 var doc = new Document(); MemoryStream memoryStream = new MemoryStream(); PdfWriter writer = PdfWriter.GetInstance(doc, memoryStream); doc.Open(); doc.Add(new Paragraph("First Paragraph")); doc.Add(new Paragraph("Second Paragraph")); writer.CloseStream = false; doc.Close(); memoryStream.Position = 0; MailMessage mm = new MailMessage("username@gmail.com", "username@gmail.com") { Subject = "subject", IsBodyHtml = true, Body = "body" }; mm.Attachments.Add(new Attachment(memoryStream, "filename.pdf")); SmtpClient smtp = new SmtpClient { Host = "smtp.gmail.com", Port = 587, EnableSsl = true, Credentials = new NetworkCredential("username@gmail.com", "password") }; smtp.Send(mm); 

Has probado:

 PdfWriter writer = PdfWriter.GetInstance(doc, memoryStream); // Build pdf code... writer.CloseStream = false; doc.Close(); // Build email memoryStream.Position = 0; mm.Attachments.Add(new Attachment(memoryStream, "test.pdf")); 

Si mi memoria me sirve correctamente, esto resolvió un problema similar en un proyecto anterior.

Ver http://forums.asp.net/t/1093198.aspx

Probé el código publicado por brianng y funcionó. Simplemente cambie la parte superior del código a esto:

 var doc = new Document(); MemoryStream memoryStream = new MemoryStream(); PdfWriter writer = PdfWriter.GetInstance(doc, memoryStream); //capture the object doc.Open(); doc.Add(new Paragraph("First Paragraph")); doc.Add(new Paragraph("Second Paragraph")); writer.CloseStream = false; //set the closestream property doc.close(); //close the document without closing the underlying stream memoryStream.Position = 0; /* remainder of your code stays the same*/ 

¿Puedes vaciar el documento o la secuencia de la memoria y luego cerrarlo después de colocarlo?

Probablemente llamar a doc.Close () Elimina la transmisión subyacente. Intente eliminar doc.Close () y en lugar de esa línea configure memoryStream.Position = 0;

Alternativamente puede usar un archivo temporal:

 var tempFilePath = Path.GetTempFileName(); try { var doc = new Document(); PdfWriter.GetInstance(doc, File.OpenWrite(tempFilePath)); doc.Open(); doc.Add(new Paragraph("First Paragraph")); doc.Add(new Paragraph("Second Paragraph")); doc.Close(); MailMessage mm = new MailMessage("username@gmail.com", "username@gmail.com") { Subject = "subject", IsBodyHtml = true, Body = "body" }; mm.Attachments.Add(new Attachment(tempFilePath, "test.pdf")); SmtpClient smtp = new SmtpClient { Host = "smtp.gmail.com", Port = 587, EnableSsl = true, Credentials = new NetworkCredential("username@gmail.com", "my_password") }; smtp.Send(mm); } finally { File.Delete(tempFilePath); } 

Tuve el mismo problema y utilicé esta publicación para resolverlo. En el código escrito por brianng

 PdfWriter writer = PdfWriter.GetInstance(doc, memoryStream); // Build pdf code... writer.CloseStream = false; doc.Close(); // Build email memoryStream.Position = 0; mm.Attachments.Add(new Attachment(memoryStream, "test.pdf")); 

Creo que en lugar de escribir

 writer.CloseStream = false and memoryStream.Position = 0; 

Solo crea una nueva secuencia

 MemoryStream m = new MemoryStream(memoryStream); 

y luego llamar

 mm.Attachments.Add(new Attachment(memoryStream, "test.pdf")); 

Ambos funcionan, pero creo que es mejor crear la nueva secuencia