Send Email Attachment Using A Memory Stream

I've been struggling to solve a file lock problem with some files I send as email attachments. I finally solved the problem by creating my documents in memory and sending the email attachment from a memory stream. This eliminated the need to write a file to disk and delete it later. I didn't find any sample code that did exactly what I wanted so I'll share the code I finally came up with.

   1: Imports System.Net.Mail
   2: Imports System.IO
   3:  
   4: Partial Class MemoryStreamAttachment
   5:     Inherits System.Web.UI.Page
   6:  
   7:     Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
   8:         Dim strMailServer As String = "mail.williamsportwebdeveloper.com"
   9:         Dim fs As New FileStream("C:\Documents and Settings\Robert Robbins\My Documents\Visual Studio 2008\WebSites\dev35\documents\Fax Cover Letter.rtf", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
  10:         Dim srTemplateReader As New StreamReader(fs)
  11:         Dim objMemoryStreamCoverLetter As New MemoryStream()
  12:         Dim strCoverLetter As New System.Text.StringBuilder("")
  13:         Dim strLine As String
  14:  
  15:         '--read through template form, replace variables and add lines to string builder
  16:         Do While srTemplateReader.Peek() >= 0
  17:             strLine = srTemplateReader.ReadLine()
  18:             '--replace [Date_Time]
  19:             strLine = strLine.Replace("[Date_Time]", Now())
  20:             '--replace [Recipient_Name]
  21:             strLine = strLine.Replace("[Recipient_Name]", "John Smith")
  22:             '--replace [Recipient_Fax]
  23:             strLine = strLine.Replace("[Recipient_Fax]", "1-555-555-5320")
  24:             '--replace [Applicant_Name]
  25:             strLine = strLine.Replace("[Applicant_Name]", "Robert S. Robbins")
  26:             strCoverLetter.Append(strLine)
  27:         Loop
  28:  
  29:         Dim enc As New UTF8Encoding
  30:         Dim arrBytData() As Byte = enc.GetBytes(strCoverLetter.ToString())
  31:         objMemoryStreamCoverLetter.Write(arrBytData, 0, arrBytData.Length)
  32:         objMemoryStreamCoverLetter.Position = 0
  33:  
  34:         '--release file system resources
  35:         srTemplateReader.Close()
  36:         srTemplateReader.Dispose()
  37:         fs.Close()
  38:         fs.Dispose()
  39:  
  40:         Dim objMM As New MailMessage
  41:         Dim objSMTP As New SmtpClient
  42:         Dim toAddress As New MailAddress("robert_robbins@verizon.net", "Robert S. Robbins")
  43:         objMM.To.Add(toAddress)
  44:         Dim fromAddress As New MailAddress("robert@williamsportwebdeveloper.com", "Robert S. Robbins")
  45:         objMM.From = fromAddress
  46:         objMM.IsBodyHtml = False
  47:         objMM.Priority = MailPriority.Normal
  48:         objMM.Subject = "Memory Stream Email Attachment"
  49:         objMM.Body = "See email attachment. Sent: " & Now()
  50:         ' add fax cover page as first file attachment
  51:         objMM.Attachments.Add(New Attachment(objMemoryStreamCoverLetter, "Fax Cover Letter.rtf"))
  52:  
  53:         Try
  54:             objSMTP.Host = strMailServer
  55:             objSMTP.DeliveryMethod = SmtpDeliveryMethod.Network
  56:             objSMTP.Credentials = New System.Net.NetworkCredential("robert@williamsportwebdeveloper.com", "******")
  57:             objSMTP.Send(objMM)
  58:             lblMessage.Text = "Mail Sent"
  59:         Catch ex As Exception
  60:             lblErrorMessage.Text = ex.Message & "<br />" & ex.StackTrace
  61:         End Try
  62:     End Sub
  63: End Class

10 Comments

  • Worked great thanks ! Just what I needed. I used this for sending SQL Reporting Services reports.

  • In addition to the above, I am using these lines of code:
    objSMTP.Port = 25;
    objSMTP.Credentials = CredentialCache.DefaultNetworkCredentials;

    I would like to know the difference in using System.Net.NetworkCredential against usingCredentialCache.DefaultNetworkCredentials

  • As cool as this might be, you might want to find a better way to post your code.

    I can't view the entire code window on my 22" monitor and you have horizontal scrollbars, which means that just to look at the code, I have to scroll my window down so I can see the scrollbar and then scroll a little bit to the right and then scroll my window back up to see if I can see the end of the line yet and then repeat till I finally see what I need. Of course I could just copy the contents and paste them into another window, but since you included line numbers and apparenly no actual line breaks, that's even more annoying.

  • Yea! An example that actually works and is exactly what I was looking for. Great job!

  • Thanks for sharing this!

    Ken

  • Pretty section of content. I just stumbled upon your site and in accession capital to assert that I acquire in fact enjoyed account your blog posts. Anyway I will be subscribing to your feeds and even I achievement you access consistently rapidly.

  • Do you have any more info on this?

  • I was having a similar problem. My issue was that when attaching a file in my email method, I was NOT disposing the attachment! This caused the file to be remained locked while in the same thread. I added the following code and did not have any locking issues from that point on! :)

    foreach(Attachment oAttach in oMail.Attachments)
    {
    oAttach.Dispose();
    }

  • How can we send multiple memory streams across layers in a single collection object. Is it possible to add multiple memory stream objects to an arraylist object?

  • Thank goodness some bloggers can write. Thanks for this article!!!

Comments have been disabled for this content.