RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Send Email Attachments On-the-Fly : Page 2

Find out how to avoid having to serialize attachments before sending them via email.

Converting Strings to Streams
Sending simple email works fine, and I'm guessing that if you have ever sent email, you figured this all out. But what if, as I mentioned earlier, you want to create the attachment "on the fly?" That is, you don't want to attach a text file—instead, you want to take the contents of a string, and attach the contents as a text file without ever saving the file on disk? No problem, you can do that. The trick lies in the overloaded versions of the constructor for the Attachment class. The class provides six overloaded versions. Three versions accept a string (plus possibly other information), where the string represents the name of a file. The other three versions allow you to supply a stream instead—the only trick then is to get the contents of the string into a stream. This task isn't as easy as you might think, however.

You can't simply convert text from a string into a stream—you must work around the conversion. You can create a new MemoryStream instance, passing to the stream's constructor the bytes you retrieve from the string itself. Of course, you can't simply retrieve the bytes from the string—you must use an encoder to do this, and the System.Text class provides several different encoders that can do the work for you. You can use the UTF32Encoding class to do the work for you, using the default encoder (see the documentation for this class for more information on all its behaviors). The GetBytes method of an encoder instance retrieves all the bytes in a specified string, like this:

   [Visual Basic]
   Dim stream As New MemoryStream( _
   MemoryStream stream = new MemoryStream(
To make it easier for my friend, I created a helper procedure, which creates the stream from the string he supplies, and then adds the attachment to the mail message (this procedure assumes you have added using/Imports statements for the System.IO and System.Text namespaces):

   [Visual Basic]
   Private Sub AddAttachmentFromStream( _
   ByVal message As MailMessage, _
   ByVal data As String, _
   ByVal attachmentName As String)
   Dim stream As New MemoryStream( _
   ' Rewind the stream.
     stream.Position = 0
   ' Create a new attachment, and
   ' add the attachment to the supplied
   ' message.
   Dim att As New Attachment( _
      stream, attachmentName)
   End Sub
   private void AddAttachmentFromStream(
    MailMessage message,
    String data,
    String attachmentName)
     MemoryStream stream = 
   new MemoryStream(
   // Rewind the stream.
     stream.Position = 0;
   // Create a new attachment, and
   // add the attachment to the supplied
   // message.
     Attachment att = new Attachment(
      stream, attachmentName);
Given this procedure, my friend wrote a test procedure like this, to try out the AddAttachmentFromStream method (with all the confidential information changed, of course):

   [Visual Basic]
   Dim sw As New StringWriter
   ' Write your data into the buffer:
   sw.WriteLine("This is some text")
   sw.WriteLine( _
    "Personalized for a recipient.")
   Dim msg As New MailMessage( _
    "someone@somewhere.com", _
    "someone@elsewhere.com", _
    "Attachments on the fly", _
    "Check out the attachment!")
   AddAttachmentFromStream(msg, _
    sw.ToString, "Attachment.txt")
   Dim client As _
   New SmtpClient("MySMTPServer")
   client.UseDefaultCredentials = True
   StringWriter sw = new StringWriter();
   MailMessage msg =
   new MailMessage(
     "Attachments on the fly",
     "Check out the attachment");
   // Write your data into the buffer:
   sw.WriteLine("This is some text");
   "Personalized for a recipient.");
   SmtpClient client =
   new SmtpClient("MySMTPServer");
   client.UseDefaultCredentials = true;
To test it out, add the AddAttachmentFromStream method to a project, add the sample code (and modify the email addresses and the SMTP server name), and give it a try. You should easily be able to generate an attachment in memory, without ever saving a text file to disk.

This isn't brain surgery—it's hardly even tricky. But it's never obvious how to convert from a string in memory into a stream, and many methods require you to supply a stream (or a file name). In those cases, if you have a string and need a stream instead, remember the technique shown here; it doesn't apply only to email attachments. Finally, repeat after me: "I won't use this power for the forces of evil." Don't start your own spamming service—I wouldn't want to be responsible for that! (And if you find a solution to the PowerPoint challenge, please let me know!)

Ken Getz is a senior consultant with MCW Technologies and splits his time between programming, writing, and training. He specializes in tools and applications written in Visual Studio .NET and Visual Basic. Ken is the author of the highly rated .Finalize() column in CoDe Magazine. He is also the co-author of several best-selling books, including Access 2002 Developer's Handbooks with Paul Litwin and Mike Gunderloy, Visual Basic Language Developer's Handbook with Mike Gilbert, and VBA Developer's Handbook with Mike Gilbert (Sybex). He co-wrote several training courses for Application Developer's Training Company, including VB.NET, ASP.NET, Access 2000 and 97, Visual Basic 6, and Visual Basic 5 seminars. He has also recorded video training for AppDev covering VB.NET, ASP.NET, VB6, Access 2000, and Access 97. Ken is a frequent speaker at technical conferences and has spoken often at Microsoft's Tech-Ed conference. Ken's also a technical editor for Access-VB-SQL Advisor magazine and a columnist for Informant Publications' asp.netPRO magazine..
Email AuthorEmail Author
Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date