Dołącz plik z MemoryStream do wiadomości MailMessage w języku C#

Piszę program do załączania pliku do e-maila. Obecnie zapisuję plik używając FileStream na dysk, a następnie używam

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

Nie chcę przechowywać pliku na dysku, chcę przechowywać plik w pamięci i ze strumienia pamięci przekazać to do Attachment.

Author: wonea, 2011-03-17

8 answers

Oto przykładowy kod.

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

Możesz określić inne typy plików za pomocą nazw System.Net.MIME. MIME, np. System.Net.Mime.MediaTypeNames.Application.Pdf

Na podstawie typu Mime należy podać poprawne rozszerzenie w nazwie pliku na przykład "myFile.pdf"

 84
Author: Waqas Raja,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-04 12:26:06

Trochę spóźniony wpis - ale mam nadzieję, że jeszcze komuś się przyda: -

Oto uproszczony fragment do wysyłania ciągu w pamięci jako załącznika e-mail (plik CSV w tym konkretnym przypadku).

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

StreamWriter i podstawowy stream nie powinny być usuwane przed wysłaniem wiadomości (aby uniknąć ObjectDisposedException: Cannot access a closed Stream).

 86
Author: tranquil tarn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-30 10:04:32

Ponieważ nie mogłem znaleźć potwierdzenia tego nigdzie, przetestowałem, czy usunięcie MailMessage i / lub obiektu załącznika spowoduje usunięcie strumienia załadowanego do nich zgodnie z oczekiwaniami.

W poniższym teście okazuje się, że gdy MailMessage jest usuwany, wszystkie strumienie używane do tworzenia załączników również zostaną usunięte. Tak długo, jak pozbędziesz się MailMessage strumienie, które weszły w jego tworzenie, nie wymagają obsługi poza tym.

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);
 23
Author: Thymine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-18 22:11:40

Jeśli rzeczywiście chcesz dodać .pdf, stwierdziłem, że konieczne jest również ustawienie pozycji strumienia pamięci na Zero.

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);
 15
Author: Jason Dimmick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-18 14:24:53

Jeśli wszystko co robisz to dołączanie Sznurka, możesz to zrobić w zaledwie 2 linijkach:

mail.Attachments.Add(Attachment.CreateAttachmentFromString("1,2,3", "text/csv");
mail.Attachments.Last().ContentDisposition.FileName = "filename.csv";
Nie udało mi się uruchomić mojego przy użyciu naszego serwera pocztowego ze Streamwriterem.
Myślę, że może dlatego, że w Streamwriterze brakuje wielu informacji o właściwościach plików, a może naszemu serwerowi nie spodobało się to, czego brakowało.
Z Przywiązaniem.CreateAttachmentFromString() stworzyło wszystko, czego potrzebowałem i działa świetnie!

W Przeciwnym Razie sugerowałbym zabranie pliku, który jest w pamięci i otwarcie go za pomocą MemoryStream( byte []) i pominięcie Streamwritera razem.

 12
Author: MikeTeeVee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-25 05:01:52

Wylądowałem na tym pytaniu, ponieważ musiałem załączyć plik Excela, który generuję za pomocą kodu i jest dostępny jako MemoryStream. Mogłem dołączyć go do wiadomości e-mail, ale został wysłany jako plik 64Bytes zamiast ~6KB, jak to miało miejsce. Więc rozwiązanie, które działało dla mnie było takie:

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

Ustawienie wartości attachment.ContentDisposition.Size pozwól mi wysyłać wiadomości o prawidłowym rozmiarze załącznika.

 2
Author: ilForna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-14 07:50:13

Użyj innego otwartego memorystream:

Przykład dla lauch pdf i wyślij pdf w MVC4 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);
    }
 1
Author: Ángel Ibáñez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-28 12:15:22

Myślę, że ten kod ci pomoże:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Net.Mail;

public partial class _Default : System.Web.UI.Page
{
  protected void Page_Load(object sender, EventArgs e)
  {

  }

  protected void btnSubmit_Click(object sender, EventArgs e)
  {
    try
    {
      MailAddress SendFrom = new MailAddress(txtFrom.Text);
      MailAddress SendTo = new MailAddress(txtTo.Text);

      MailMessage MyMessage = new MailMessage(SendFrom, SendTo);

      MyMessage.Subject = txtSubject.Text;
      MyMessage.Body = txtBody.Text;

      Attachment attachFile = new Attachment(txtAttachmentPath.Text);
      MyMessage.Attachments.Add(attachFile);

      SmtpClient emailClient = new SmtpClient(txtSMTPServer.Text);
      emailClient.Send(MyMessage);

      litStatus.Text = "Message Sent";
    }
    catch (Exception ex)
    {
      litStatus.Text = ex.ToString();
    }
  }
}
 -5
Author: r12,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-24 03:54:30