问题
Our project has files stored in a sql server db as blobs. I'd like to get the files from the database and attach multiple files to an email without writing to disk.
This is what I have so far(everything works ok, with no attachments):
// snip
List<System.Net.Mail.Attachment> attachments = null;
// Attachments is a child list of Messagebody object holding Attachment ids
MessageBody.Attachments = MessageBodyAttachmentList.GetMessageBodyAttachmentList(this.MessageBody.ID);
if (MessageBody.Attachments != null && MessageBody.Attachments.Count > 0)
{
attachments = new List<Attachment>();
foreach (Library.Entity.Messaging.MessageBodyAttachment att in MessageBody.Attachments)
{
using (MemoryStream memoryStream = new MemoryStream())
{
// create a new attachment
Library.Attachments.Attachment attachment = Library.Attachments.Attachment.GetAttachment(att.AttachmentID);
byte[] contentAsBytes = attachment.FileData;// FileData holds byte[] that is the contents of the file
memoryStream.Write(contentAsBytes, 0, contentAsBytes.Length);
memoryStream.Seek(0, SeekOrigin.Begin);
// content type for file info
ContentType contentType = new ContentType();
contentType.MediaType = MediaTypeNames.Application.Octet;
contentType.Name = attachment.FileName;
// create the .Net specific attachment
Attachment netAttachment = new Attachment(memoryStream, contentType);
attachments.Add(netAttachment);
memoryStream.Position = 0;
}
}
}
response = message.SendMessage(_recipient, _sender, _cc, _bcc, MessageBody.Subject, MessageBody.Body, true, attachments);
// snip
public string SendMessage(string to, string from, string cc, string bcc, string subject, string body, bool IsHtml, List<Attachment> attachments)
{
string response = String.Empty;
System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage(from, to, subject, body);
// Add the attachments
if (attachments != null)
{
foreach (Attachment a in attachments)
message.Attachments.Add(a);
}
message.IsBodyHtml = IsHtml;
if (IsHtml)
{
// snip
}
try
{
_client.Timeout = 500000;
_client.Send(message);
}
catch (SmtpException smtpex)
{
response = smtpex.Message;
}
catch (System.Exception ex)
{
response = ex.Message;
}
return response;
}
I'm getting the following errors:
exception message: Failure sending mail.
source: System
stack trace:
at System.Net.Mail.SmtpClient.Send(MailMessage message)
at MyCompany.Shared.Email.SMTPMessage.SendMessage(String to, String from, String cc, String bcc, String subject, String body, Boolean IsHtml, List`1 attachments) in C:\svn_repos\branches\2010.02.28\Net\Common\Shared\Email\SMTPMessage.cs:line 116
inner exception msg: Cannot access a closed Stream.
inner source: mscorlib
inner targetsite: {Void StreamIsClosed()}
inner stack trace:
at System.IO.__Error.StreamIsClosed()
at System.IO.MemoryStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.Net.Mime.MimePart.Send(BaseWriter writer)
at System.Net.Mime.MimeMultiPart.Send(BaseWriter writer)
at System.Net.Mail.Message.Send(BaseWriter writer, Boolean sendEnvelope)
at System.Net.Mail.MailMessage.Send(BaseWriter writer, Boolean sendEnvelope)
at System.Net.Mail.SmtpClient.Send(MailMessage message)
I copied most of the stream code from examples I found on the web.
回答1:
You've found a reason to not implement a using
block: when you're still going to use the object after the block has exited. Take the MemoryStream
out of the using
block.
来源:https://stackoverflow.com/questions/2165955/attach-multiple-files-to-an-email-programticaly-without-writing-to-disk