2010-01-29 28 views
7

Nuestro proyecto tiene archivos almacenados en un servidor sql db como blobs. Me gustaría obtener los archivos de la base de datos y adjuntar varios archivos a un correo electrónico sin escribir en el disco.adjuntar varios archivos a un correo electrónico programéticamente sin escribir en el disco

Esto es lo que tengo hasta el momento (todo funciona bien, sin los accesorios):

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

Me estoy poniendo los siguientes errores:

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) 

he copiado la mayor parte del código de corriente de ejemplos que encontré en la web.

+0

1. No use pestañas (use espacios), haga que sea más fácil corregir el formato para la web, y 2. Para publicar el código en Desbordamiento de pila, sangría cada línea por 4 espacios (puede seleccionar el código posteriormente y presionar Ctrl + K o use el botón de la barra de herramientas) –

Respuesta

10

Has encontrado una razón para no implementar un bloque using: cuando todavía vas a utilizar el objeto después de que el bloque haya salido. Tome el MemoryStream fuera del bloque using.

+1

Tiene razón, el bloque en uso estaba causando los problemas. Lo rehice a algo como esto: memorystream ms = null; si (no tengo los archivos adjuntos) ms = nueva MemoryStream() Do creación apego Enviar mensaje si (ms! = Null) Do limpieza Gracias por su ayuda. –

+2

¿Cómo usaste el flujo de memoria para manejar múltiples archivos adjuntos? Creé 1 por cada uno y los eliminé manualmente, pero quería ver si había una mejor manera, y también para asegurarme de no crear ninguna pérdida de memoria. Thx –

+0

Tengo la misma pregunta. – Kate

Cuestiones relacionadas