web-dev-qa-db-fra.com

iTextSharp - Envoi de pdf en mémoire dans une pièce jointe à un e-mail

J'ai posé quelques questions ici, mais j'ai toujours des problèmes. J'apprécierais si vous pouviez me dire ce que je fais mal dans mon code. J'exécute le code ci-dessus à partir d'une page ASP.Net et j'obtiens "Impossible d'accéder à un flux fermé".

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("[email protected]", "[email protected]")
{
    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("[email protected]", "my_password")
};

smtp.Send(mm); //the "Cannot Access a Closed Stream" error is thrown here

Merci!!!

MODIFIER:

Juste pour aider quelqu'un qui cherche la réponse à cette question, le code pour envoyer un fichier pdf joint à un email sans avoir à créer physiquement le fichier est ci-dessous (merci à Ichiban et 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("[email protected]", "[email protected]")
{
    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("[email protected]", "password")

};

smtp.Send(mm);
97
Gus Cavalcanti

As-tu essayé:

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 ma mémoire est bonne, cela a résolu un problème similaire dans un projet précédent.

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

79
brianng

J'ai essayé le code posté par brianng et cela a fonctionné. Changez simplement le haut du code en ceci:

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*/
18
ichiban

Probablement appel à doc.Close () Supprime le flux sous-jacent. Essayez de supprimer doc.Close () et au lieu de cette ligne, définissez memoryStream.Position = 0;

Vous pouvez également utiliser un fichier temporaire:

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("[email protected]", "[email protected]")
    {
        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("[email protected]", "my_password")
    };

    smtp.Send(mm);
}
finally
{
    File.Delete(tempFilePath);
}
3
huseyint

Pouvez-vous vider le document ou le flux de mémoire, puis le fermer après l'avoir joint?

3
James Conigliaro

J'ai eu le même problème et j'ai utilisé ce post pour le résoudre. Dans le code écrit par 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"));

Je pense qu'au lieu d'écrire

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

Créez simplement un nouveau Stream

MemoryStream m = new MemoryStream(memoryStream);

puis appeler

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

Les deux fonctionnent mais je pense qu'il vaut mieux créer le nouveau stream

1
Zein Sleiman