Question Joindre un fichier de MemoryStream à un MailMessage en C #


J'écris un programme pour joindre un fichier à un courrier électronique. 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")); 

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


85
2018-03-17 07:45


origine


Réponses:


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();
ms.Position = 0;

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

Basé sur Type de mime vous devez spécifier une extension correcte dans FileName par exemple "myFile.pdf"


83
2018-03-17 08:04



Une entrée tardive - mais peut-être utile pour quelqu'un: -

Voici un extrait simplifié pour l'envoi d'une chaîne en mémoire en tant que pièce jointe à un courrier électronique (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);
}

Le StreamWriter et le flux sous-jacent ne doivent pas être éliminés tant que le message n’a pas été envoyé (pour éviter ObjectDisposedException: Cannot access a closed Stream).


83
2018-02-12 19:04



Comme je ne pouvais pas trouver de confirmation de ceci quelque part, j'ai testé si l'élimination de l'objet MailMessage et / ou de la pièce jointe éliminerait le flux chargé comme prévu.

Avec le test suivant, il apparaît que lorsque le message MailMessage est supprimé, tous les flux utilisés pour créer des pièces jointes seront également supprimés. Donc, tant que vous jetez votre MailMessage, les flux entrés dans sa création n'ont pas besoin d'être manipulé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);

22
2017-10-18 22:11



Si vous voulez réellement ajouter un fichier .pdf, j'ai également jugé nécessaire de définir la position du flux de mémoire sur zéro.

var memStream = new MemoryStream(yourPdfByteArray);
memStream.Position = 0;
var contentType = new System.Net.Mime.ContentType(System.Net.Mime.MediaTypeNames.Application.Pdf);
var reportAttachment = new Attachment(memStream, contentType);
reportAttachment.ContentDisposition.FileName = "yourFileName.pdf";
mailMessage.Attachments.Add(reportAttachment);

13
2017-10-21 14:25



Si tout ce que vous faites 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 faire fonctionner le mien en utilisant notre serveur de messagerie avec StreamWriter.
Je pense que peut-être parce qu'avec StreamWriter, il vous manque beaucoup d'informations sur les propriétés des fichiers et peut-être que notre serveur n'aimait pas ce qui manquait.
Avec Attachment.CreateAttachmentFromString (), il a créé tout ce dont j'avais besoin et fonctionne très bien!

Sinon, je vous suggère de prendre votre fichier en mémoire et de l’ouvrir en utilisant MemoryStream (byte []) et en ignorant tous les fichiers StreamWriter.


12
2017-10-25 05:01



J'ai atterri sur cette question parce que je devais joindre un fichier Excel que je génère via le code et est disponible en tant que MemoryStream. Je pouvais le joindre au message mais il a été envoyé sous forme de fichier 64Bytes au lieu de ~ 6KB. Donc, la solution qui a fonctionné pour moi était la suivante:

MailMessage mailMessage = new MailMessage();
Attachment attachment = new Attachment(myMemorySteam, new ContentType(MediaTypeNames.Application.Octet));

attachment.ContentDisposition.FileName = "myFile.xlsx";
attachment.ContentDisposition.Size = attachment.Length;

mailMessage.Attachments.Add(attachment);

Définir la valeur de attachment.ContentDisposition.Size laissez-moi envoyer des messages avec la taille de pièce jointe correcte.


2
2018-06-14 07:50



utilisez AUTRE OPEN memorystream:

exemple pour pdf de lancement et envoi de pdf dans le contrôleur de MVC4 C #

        public void ToPdf(string uco, int idAudit)
    {
        Response.Clear();
        Response.ContentType = "application/octet-stream";
        Response.AddHeader("content-disposition", "attachment;filename= Document.pdf");
        Response.Buffer = true;
        Response.Clear();

        //get the memorystream pdf
        var bytes = new MisAuditoriasLogic().ToPdf(uco, idAudit).ToArray();

        Response.OutputStream.Write(bytes, 0, bytes.Length);
        Response.OutputStream.Flush();

    }


    public ActionResult ToMail(string uco, string filter, int? page, int idAudit, int? full) 
    {
        //get the memorystream pdf
        var bytes = new MisAuditoriasLogic().ToPdf(uco, idAudit).ToArray();

        using (var stream = new MemoryStream(bytes))
        using (var mailClient = new SmtpClient("**YOUR SERVER**", 25))
        using (var message = new MailMessage("**SENDER**", "**RECEIVER**", "Just testing", "See attachment..."))
        {

            stream.Position = 0;

            Attachment attach = new Attachment(stream, new System.Net.Mime.ContentType("application/pdf"));
            attach.ContentDisposition.FileName = "test.pdf";

            message.Attachments.Add(attach);

            mailClient.Send(message);
        }

        ViewBag.errMsg = "Documento enviado.";

        return Index(uco, filter, page, idAudit, full);
    }

1
2017-09-28 12:15