Stream closed error when adding attachment to MailMessage

我怕爱的太早我们不能终老 提交于 2019-12-01 13:42:55

问题


I use the following code to attach a file to an email message.

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.

The error message is: //Error: System.ObjectDisposedException: Cannot access a closed Stream

Im guessing that the "USING" statement closes the stream when exiting the block. But why doesnt "Attacments.Add()" make its own copy of the stream?


回答1:


The Send() method is going to access the attachments to embed them into the mail message. That goes kaboom here, the memory stream was disposed. You need to move the Send() call inside of the using statements so the stream doesn't get disposed until after the message is sent.

Mentioning that using isn't necessary here because a memory stream doesn't have any unmanaged resources that need to be disposed always gets me into trouble at SO. So I won't bring that up.




回答2:


One solution I found to this when I was dealing with a scenario where the MailMessage was being created separate from the sending and potentially with multiple attachments was to use a List of MemoryStream objects

// Tuple contains displayName and byte[] content for attachment in this case
List<Tuple<string,byte[]>> attachmentContent;
MailMessage email = BuildNativeEmail(requestObject, out attachmentContent);
List<MemoryStream> streams = new List<MemoryStream>();
foreach(Tuple<string,byte[]> 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();
}



回答3:


Yes.Its true.Using statement closes the stream when exiting the block.

Don't use "Using" statement.After sending email call dispose() method for Attachments.

...
...
msg.Send();

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

You can also use the same way for AlternateView.

...
...
msg.AlternateViews.Add(alternateView);

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



回答4:


Use :

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



回答5:


Put the using on the MailMessage, it will internally dispose of the streams that make up the attachments

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


来源:https://stackoverflow.com/questions/5252271/stream-closed-error-when-adding-attachment-to-mailmessage

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!