126 votes

Comment joindre un fichier de MemoryStream à un MailMessage en c #

Je suis en train d'écrire un programme pour joindre un fichier à un email. Actuellement, je sauvegarde le fichier en utilisant FileStream sur le disque, puis j'utilise

 System.Net.Mail.MailMessage.Attachments.Add(
    new System.Net.Mail.Attachment("file name")); 
 

Mais je ne veux pas stocker le fichier sur le disque, je veux stocker le fichier en mémoire et à partir du flux de mémoire, transmettez-le à Attachment .

117voto

Waqas Raja Points 5942

Voici l exemple de code.

 System.IO.MemoryStream ms = new System.IO.MemoryStream();
System.IO.StreamWriter writer = new System.IO.StreamWriter(ms);
writer.Write("Hello its my sample file");
writer.Flush();
writer.Dispose();

System.Net.Mime.ContentType ct = new System.Net.Mime.ContentType(System.Net.Mime.MediaTypeNames.Text.Plain);
System.Net.Mail.Attachment attach = new System.Net.Mail.Attachment(ms, ct);
attach.ContentDisposition.FileName = "myFile.txt";

// I guess you know how to send email with an attachment
// after sending email
ms.Close();
 

Modifier 1

Vous pouvez spécifier d'autres types de fichiers par System.Net.Mime.MimeTypeNames comme System.Net.Mime.MediaTypeNames.Application.Pdf

En fonction du type MIME, vous devez spécifier l'extension correcte dans FileName pour l'instance "myFile.pdf"

101voto

tranquil tarn Points 576

Une entrée tardive - mais j'espère toujours utile à quelqu'un: -

Voici un extrait simplifié pour envoyer une chaîne en mémoire sous forme de pièce jointe à un e-mail (un fichier CSV dans ce cas particulier).

 using (var stream = new MemoryStream())
using (var writer = new StreamWriter(stream))    // using UTF-8 encoding by default
using (var mailClient = new SmtpClient("localhost", 25))
using (var message = new MailMessage("me@example.com", "you@example.com", "Just testing", "See attachment..."))
{
    writer.WriteLine("Comma,Seperated,Values,...");
    writer.Flush();
    stream.Position = 0;     // read from the start of what was written

    message.Attachments.Add(new Attachment(stream, "filename.csv", "text/csv"));

    mailClient.Send(message);
}
 

StreamWriter et le flux sous-jacent ne doivent pas être supprimés avant l'envoi du message (pour éviter ObjectDisposedException: Cannot access a closed Stream ).

33voto

Thymine Points 2198

N'ayant pu trouver aucune confirmation de cela nulle part, j'ai vérifié si l'élimination de MailMessage et / ou l'objet Attachment suppriment le flux chargé comme prévu.

Le test suivant semble indiquer que lorsque MailMessage est supprimé, tous les flux utilisés pour créer des pièces jointes le seront également. Par conséquent, tant que vous disposez de votre MailMessage, les flux entrés dans sa création n’ont pas besoin d’être gérés.

 MailMessage mail = new MailMessage();
//Create a MemoryStream from a file for this test
MemoryStream ms = new MemoryStream(File.ReadAllBytes(@"C:\temp\test.gif"));

mail.Attachments.Add(new System.Net.Mail.Attachment(ms, "test.gif"));
if (mail.Attachments[0].ContentStream == ms) Console.WriteLine("Streams are referencing the same resource");
Console.WriteLine("Stream length: " + mail.Attachments[0].ContentStream.Length);

//Dispose the mail as you should after sending the email
mail.Dispose();
//--Or you can dispose the attachment itself
//mm.Attachments[0].Dispose();

Console.WriteLine("This will throw a 'Cannot access a closed Stream.' exception: " + ms.Length);
 

13voto

MikeTeeVee Points 3578

Si tout ce que vous avez à faire est d'attacher une chaîne, vous pouvez le faire en seulement 2 lignes:

mail.Attachments.Add(Attachment.CreateAttachmentFromString("1,2,3", "text/csv");
mail.Attachments.Last().ContentDisposition.FileName = "filename.csv";

Je n'ai pas pu obtenir le mien fonctionne à l'aide de notre serveur de messagerie avec StreamWriter.
Je pense peut-être parce qu'avec StreamWriter vous manque beaucoup de fichier les informations de propriété et peut-être que notre serveur n'aime pas ce qui manquait.
Avec Pièce Jointe.CreateAttachmentFromString() il a créé tout ce dont j'ai besoin et fonctionne très bien!

Sinon, je vous suggère de prendre votre fichier dans la mémoire et de l'ouvrir à l'aide de MemoryStream(byte[]), et le saut de l'StreamWriter tous ensemble.

0voto

Red Swan Points 3073

essayez ce lien

une fois que vous avez terminé votre envoi, supprimez le fichier stocké temporaire dans l'état de l'envoi du courrier.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X