将MemoryStream中的文件附加到C#中的MailMessage

我正在编写一个程序来附加一个文件到电子邮件。 目前我正在使用FileStream将文件保存到磁盘中,然后使用

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

我不想将文件存储在磁盘中,我想将文件存储在内存中,并从内存stream中传递给Attachment

这里是示例代码。

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

编辑1

您可以通过System.Net.Mime.MimeTypeNames指定其他文件types,如System.Net.Mime.MediaTypeNames.Application.Pdf

基于MIMEtypes,您需要在FileName中指定正确的扩展名,例如"myFile.pdf"

有点迟到 – 但希望仍然有用的人在那里: –

这是一个简单的片段,用于发送内存中的string作为电子邮件附件(在这种情况下是一个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和基础stream不应该被处理,直到消息发送之后(以避免ObjectDisposedException: Cannot access a closed Stream )。

由于我无法在任何地方find确认,所以我testing了如果处理MailMessage和/或Attachment对象会像我预期的那样将stream加载到它们中。

它确实出现在下面的testing中,当MailMessage被处置时,用于创build附件的所有stream也将被处置。 所以只要你处理你的MailMessage,创build它的stream不需要处理。

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

如果你真的想添加一个.pdf,我发现它也有必要将内存stream的位置设置为零。

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

如果你所做的只是附加一个string,你可以用两行来完成:

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

我无法使用StreamWriter使用我们的邮件服务器。
我想可能是因为在StreamWriter中,你错过了很多文件属性信息,也许我们的服务器不喜欢丢失的东西。
随着Attachment.CreateAttachmentFromString()它创造了我需要的一切,并且工作很棒!

否则,我会build议把你的文件放到内存中,用MemoryStream(byte [])打开它,然后一起跳过StreamWriter。

我登陆这个问题,因为我需要附加一个Excel文件,我通过代码生成,可作为MemoryStream 。 我可以将它附加到邮件消息中,但它是以64Bytes文件的forms发送的,而不是像本意的那样发送到〜6KB。 所以,为我工作的解决scheme是这样的:

 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的值让我发送正确大小的附件。

使用OTHER OPEN memorystream:

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

我认为这个代码将帮助你:

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