2010-01-29 5 views
7

Il nostro progetto ha file memorizzati in un db del server SQL come blob. Mi piacerebbe ottenere i file dal database e allegare più file a una e-mail senza scrivere sul disco.allegare più file a una posta elettronica programmatica senza scrivere sul disco

Questo è quello che ho finora (tutto funziona bene, senza allegati):

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

sto ottenendo i seguenti errori:

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) 

ho copiato la maggior parte del codice di flusso dagli esempi che ho trovato sul web.

+0

1. non utilizzare le schede (usa spazi), rende più facile correggere la formattazione per il web e 2. per inserire il codice su Stack Overflow, rientra ogni riga di 4 spazi (puoi selezionare il codice successivamente e premere Ctrl + K o utilizza il pulsante della barra degli strumenti) –

risposta

10

Hai trovato un motivo per non implementare un blocco using: quando continuerai a utilizzare l'oggetto dopo che il blocco è stato chiuso. Prendi lo MemoryStream dal blocco using.

+1

Hai ragione, il blocco utilizza stava causando i problemi. L'ho rifatto a qualcosa del genere: memorystream ms = null; se (ho allegati) ms = nuovo MemoryStream() Do creazione attaccamento Invia un messaggio se (ms! = Null) Do pulizia Grazie per il vostro aiuto. –

+2

Come hai utilizzato lo stream di memoria per gestire più allegati? Ho creato 1 per e li ho smaltiti manualmente, ma volevo vedere se c'era un modo migliore, e anche per assicurarmi di non creare perdite di memoria - thx –

+0

Ho la stessa domanda. – Kate

Problemi correlati