向MailMessage添加附件时流关闭错误

我使用以下代码将文件附加到电子邮件中。

msg = new MailMessage(); using (strMem = new MemoryStream((byte[])attDr["filedata"])) { using (strWriter = new StreamWriter(strMem)) { strWriter.Flush(); strMem.Position = 0; using (attachment = new Attachment(strMem, attDr["filename"].ToString())) { msg.Attachments.Add(attachment); } } } ... ... msg.Send(); //Error: System.ObjectDisposedException: Cannot access a closed Stream. 

错误消息是://错误:System.ObjectDisposedException:无法访问已关闭的Stream

我猜测“USING”语句在退出块时关闭流。 但为什么“Attacments.Add()”没有制作自己的流副本?

Send()方法将访问附件以将它们嵌入到邮件消息中。 这就是kaboom,内存流被处理掉了。 您需要在using语句中移动Send()调用,以便在发送消息之前不会释放流。

提到在这里没有必要使用因为内存流没有任何需要处理的非托管资源总是让我陷入麻烦。 所以我不会提起这件事。

我在处理正在创建MailMessage的场景时发现的一个解决方案与发送分开,可能还有多个附件是使用List of MemoryStream对象

 // Tuple contains displayName and byte[] content for attachment in this case List> attachmentContent; MailMessage email = BuildNativeEmail(requestObject, out attachmentContent); List streams = new List(); foreach(Tuple attachment in attachmentContent) { MemoryStream m = new MemoryStream(attachment.Item2); email.Attachments.Add(new System.Net.Mail.Attachment(m, attachment.Item1)); streams.add(m); } // client represents a System.Net.Mail.SmtpClient object client.Send(email); foreach(MemoryStream stream in streams) { stream.Dispose(); } 

Yes.Its true.Using语句在退出块时关闭流。

不要使用“ 使用 ”语句。发送电子邮件后调用dispose()方法进行附件

 ... ... msg.Send(); msg.Attachments.ToList().ForEach(x => x.ContentStream.Dispose()); 

您也可以使用相同的方式AlternateView

 ... ... msg.AlternateViews.Add(alternateView); ... msg.Send(); ... if (alternateView != null) { mail.AlternateViews.Dispose(); } 

使用 :

 using (strMem = new MemoryStream((byte[])attDr["filedata"])) { using (strWriter = new StreamWriter(strMem)) { strWriter.Flush(); strMem.Position = 0; using (attachment = new Attachment(attDr["filename"].ToString())) { strMem.CopyTo(attachment.ContentStream); msg.Attachments.Add(attachment); } } } 

将使用放在MailMessage上 ,它将在内部处理组成附件的流

 using(var msg = new MailMessage()) { ... ... var attachment = new Attachment(strMem, filename,contentType); msg.Attachments.Add(attachment); ... ... msg.Send(); }