MemoryStream의 파일을 C #의 MailMessage에 첨부


113

이메일에 파일을 첨부하는 프로그램을 작성 중입니다. 현재 파일을 사용 FileStream하여 디스크에 저장 하고 있습니다.

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

디스크에 파일을 저장하고 싶지 않고 파일을 메모리에 저장하고 메모리 스트림에서 Attachment.

답변:


104

다음은 샘플 코드입니다.

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

편집 1

System.Net.Mime.MimeTypeNames로 다른 파일 형식을 지정할 수 있습니다. System.Net.Mime.MediaTypeNames.Application.Pdf

를 기반으로 마임 유형 당신은 예를 들어 파일 이름에 올바른 확장자를 지정해야"myFile.pdf"


PDF를 사용하고 있습니다.이 유형을 System.Net.Mime.ContentType에 전달하는 방법 ct = new System.Net.Mime.ContentType (System.Net.Mime.MediaTypeNames.Text.Plain);
Zain Ali

3
당신은 사용해야합니다System.Net.Mime.MediaTypeNames.Application.Pdf
Waqas Raja 2011

5
writer.Disopose()내 솔루션에는 너무 이르지만 다른 모든 것은 훌륭한 예입니다.
Kazimierz Jawor

7
ms.Position = 0;첨부 파일을 만들기 전에이 있어야한다고 확신 합니다.
Kenny Evitt 2017 년

94

약간의 늦은 입장-그러나 다른 사람에게 여전히 유용하기를 바랍니다.

다음은 메모리 내 문자열을 이메일 첨부 파일 (이 특정 경우에는 CSV 파일)로 보내기위한 간단한 스 니펫입니다.

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 및 기본 스트림은 메시지가 전송 될 때까지 삭제되어서는 안됩니다 ObjectDisposedException: Cannot access a closed Stream.


30
어떤 이민자를 위해, 나를 위해 키를 설정했다stream.position = 0;
mtbennett

3
using ()의 적절한 사용을위한 +1-온라인 예제 및 스 니펫에서 항상 누락 된 것 같습니다 (이 질문에 대한 답변 포함).
Jay Querido 2014-08-15

2
내 문제 설정이기도 한 @mtbennet 덕분 stream.Position=0입니다.
Icarus 2014

여기서 MIME 유형 설정은 실제로 무엇을합니까? 이메일 클라이언트 앱을위한 것이 있습니까?
xr280xr

@ xr280xr-맞습니다. 이 매개 변수는 실제로 필수는 아니지만이를 포함하면 수신자의 이메일 클라이언트가 첨부 파일을 현명하게 처리하는 데 도움이됩니다. docs.microsoft.com/en-us/dotnet/api/…
고요한 tarn

28

어디에서나 이에 대한 확인을 찾을 수 없었기 때문에 MailMessage 및 / 또는 Attachment 개체를 처리하면 예상대로로드 된 스트림이 처리되는지 테스트했습니다.

다음 테스트에서는 MailMessage가 삭제 될 때 첨부 파일을 만드는 데 사용 된 모든 스트림도 삭제됩니다. 따라서 MailMessage를 폐기하는 한 생성에 들어간 스트림은 그 이상으로 처리 할 필요가 없습니다.

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

젠장, 영리 하군. 한 줄의 코드 만 있으면 이미지 파일을 이메일에 첨부 파일로 추가 할 수 있습니다. 좋은 팁!
Mike Gledhill 2015 년

나는 이것이 실제로 문서화되기를 바랍니다. 이 동작에 대한 테스트 / 검증은 유용하지만 공식 문서에 포함되어 있지 않으면 이것이 항상 해당 될 것이라고 믿기가 어렵습니다. 어쨌든 테스트 해 주셔서 감사합니다.
Lucas

좋은 노력과 연구 @thymine
vibs2006

1
참조 출처가 중요하다면 일종의 문서화입니다. mailmessage.disposeattachments.dispose 를 호출 하고, 차례로 각 첨부 파일에 대해 dispose를 호출 하여 mimepart 에서 스트림을 닫습니다 .
Cee McSharpface

감사합니다. 메일 메시지가 실제로 전송되는 위치와 다른 클래스에서 메시지를 작성하고 있기 때문에 메일 메시지가 그렇게해야하고 필요하다고 생각했습니다.
xr280xr

20

실제로 .pdf를 추가하려면 메모리 스트림의 위치를 ​​0으로 설정해야합니다.

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

pdf를 보내는 데 시간을 보내십시오. 이것은 매력처럼 작동했습니다!
dijam 2016

12

만약 당신이하고있는 모든 것이 문자열을 붙이는 것이라면, 단 두 줄로 할 수 있습니다 :

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

StreamWriter와 함께 메일 서버를 사용하여 작업 할 수 없었습니다.
StreamWriter를 사용하면 많은 파일 속성 정보가 누락되고 서버가 누락 된 항목이 마음에 들지 않았기 때문일 수 있습니다.
Attachment.CreateAttachmentFromString ()을 사용하면 필요한 모든 것을 만들었고 훌륭하게 작동합니다!

그렇지 않으면 메모리에있는 파일을 가져와 MemoryStream (byte [])을 사용하여 열고 StreamWriter를 모두 건너 뛰는 것이 좋습니다.


2

코드를 통해 생성 한 Excel 파일을 첨부해야하므로 MemoryStream. 나는 그것을 메일 메시지에 첨부 할 수 있지만 그것이 의미하는대로 ~ 6KB 대신 64Bytes 파일로 전송되었습니다. 그래서 나를 위해 일한 해결책은 다음과 같습니다.

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

값 설정 attachment.ContentDisposition.Size올바른 크기의 첨부 파일로 메시지를 보내도록 허용 .


2

OTHER OPEN 메모리 스트림 사용 :

lauch pdf의 예 및 MVC4 C # 컨트롤러에서 pdf 보내기

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

stream.Position=0; 나를 도운 라인입니다. 그것 없이는 내 attcahment가 일부 kB의 504 바이트에 불과했습니다
Abdul Hameed

-6

이 코드가 도움이 될 것이라고 생각합니다.

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
-1이 대답은 Attachment (string fileName) 생성자를 사용하여 디스크에서 첨부 파일을로드합니다. OP는 구체적으로 디스크에서로드하지 않기를 원합니다. 또한 이것은 Red Swan의 답변 링크에서 복사하여 붙여 넣은 코드입니다.
Walter Stabosz 2013

attachFile 스트림도 삭제되지 않음
Sameh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.