2010-01-29 7 views
7

Notre projet a des fichiers stockés dans un serveur sql db sous forme de blobs. Je voudrais obtenir les fichiers de la base de données et joindre plusieurs fichiers à un courriel sans écrire sur le disque.Joindre plusieurs fichiers à un programme électronique sans écrire sur le disque

C'est ce que j'ai jusqu'à présent (tout fonctionne bien, sans pièces jointes):

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

Je reçois les erreurs suivantes:

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) 

j'ai copié la plupart du code de flux d'exemples que j'ai trouvés sur le web.

+0

1. n'utilisez pas d'onglets (utilisez des espaces), facilite la mise en forme pour le web, et 2. pour afficher du code sur Stack Overflow, indiquez chaque ligne de 4 espaces (vous pouvez ensuite sélectionner le code et appuyer sur Ctrl + K ou utilisez le bouton de la barre d'outils) –

Répondre

10

Vous avez trouvé une raison pour ne pas implémenter un bloc using: lorsque vous allez toujours utiliser l'objet après la fermeture du bloc. Prenez le MemoryStream dans le bloc using.

+1

Vous avez raison, le bloc utilisant était à l'origine des problèmes. Je l'ai refait à quelque chose comme ceci: memorystream ms = null; si (je les pièces jointes) ms = new MemoryStream() Do création de fixation Envoyer un message si (ms! = Null) Do nettoyage Merci pour votre aide. –

+2

Comment avez-vous utilisé le flux de mémoire pour gérer plusieurs pièces jointes? J'ai créé 1 par et manuellement éliminés d'eux mais je voulais voir s'il y avait une meilleure façon, et aussi pour m'assurer que je ne crée pas de fuites de mémoire - thx –

+0

J'ai la même question. – Kate