it-swarm.com.de

Eine Datei aus MemoryStream an eine MailMessage in C # anhängen

Ich schreibe ein Programm zum Anhängen einer Datei an eine E-Mail. Derzeit speichere ich die Datei mit FileStream auf der Festplatte und verwende dann

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

Ich möchte keine Datei auf der Festplatte speichern, ich möchte eine Datei im Speicher speichern und diese vom Speicherstrom an Attachment übergeben.

104
Zain Ali

Hier ist der Beispielcode.

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();

Edit 1

Sie können andere Dateitypen durch System.Net.Mime.MimeTypeNames wie System.Net.Mime.MediaTypeNames.Application.Pdf Angeben.

Basierend auf Mime Type müssen Sie die korrekte Erweiterung in FileName angeben, zum Beispiel "myFile.pdf"

94
Waqas Raja

Ein bisschen verspäteter Einstieg - aber hoffentlich immer noch nützlich für jemanden da draußen:

Hier ist ein vereinfachtes Snippet zum Senden einer In-Memory-Zeichenfolge als E-Mail-Anhang (in diesem speziellen Fall eine CSV-Datei).

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

Der StreamWriter und der zugrunde liegende Stream sollten erst nach dem Senden der Nachricht entsorgt werden (um ObjectDisposedException: Cannot access a closed Stream Zu vermeiden).

91
tranquil tarn

Da ich nirgendwo eine Bestätigung dafür finden konnte, habe ich getestet, ob das Entsorgen der MailMessage und/oder des Attachment-Objekts den in sie geladenen Stream so entsorgen würde, wie ich es erwartet hatte.

Mit dem folgenden Test wird festgestellt, dass beim Löschen der MailMessage auch alle zum Erstellen von Anhängen verwendeten Streams gelöscht werden. Solange Sie Ihre MailMessage entsorgen, müssen die erstellten Streams nicht weiter bearbeitet werden.

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);
24
Thymine

Wenn Sie tatsächlich eine PDF-Datei hinzufügen möchten, musste die Position des Speicherstroms auf Null gesetzt werden.

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);
17
Jason Dimmick

Wenn Sie nur eine Zeichenfolge anhängen, können Sie dies in nur zwei Zeilen tun:

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

Ich war nicht in der Lage, meinen Mailserver mit StreamWriter zum Laufen zu bringen.
Ich denke, vielleicht, weil Sie mit StreamWriter viele Informationen zu Dateieigenschaften vermissen und vielleicht unserem Server nicht gefallen hat, was fehlte.
Mit Attachment.CreateAttachmentFromString () wurde alles erstellt, was ich brauchte, und es funktioniert großartig!

Andernfalls würde ich vorschlagen, Ihre im Speicher befindliche Datei mit MemoryStream (Byte []) zu öffnen und den StreamWriter insgesamt zu überspringen.

12
MikeTeeVee

benutze OTHER OPEN memorystream:

beispiel zum Starten von pdf und Senden von pdf in MVC 4 C # Controller

        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);
    }
2
Ángel Ibáñez

Ich bin auf diese Frage gestoßen, weil ich eine Excel-Datei anhängen musste, die ich mit Code erstellt habe und die als MemoryStream verfügbar ist. Ich könnte es an die E-Mail-Nachricht anhängen, aber es wurde als 64-Byte-Datei anstelle von ~ 6 KB gesendet, wie es gemeint war. Die Lösung, die für mich funktioniert hat, war:

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);

Einstellen des Werts von attachment.ContentDisposition.Size Ich möchte Nachrichten mit der richtigen Größe des Anhangs senden.

2
ilForna