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


Send Email Attachments On-the-Fly

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

ou know what drives me nuts (among so many other things)? What's making me crazy this week is the requirement—in so many areas of programming—that you must serialize data into a file on disk before you can programmatically work with that data. Don't believe that this is an issue?

Here's a challenge for you: Store an image in a database somewhere. Now, using the language of your choice, write code that retrieves that image and creates a new picture box on a slide, in Microsoft PowerPoint, that contains that image. I tried. Perhaps I missed the point, but the only way I could accomplish this task was to store the image into a disk file, and then retrieve the image from the disk file and display it on the slide. Although this isn't a difficult task, the fact that I have to do it really irks me. Solving the problem this way is slow, totally unscalable, and as far as I can tell, the only way to solve the problem.

Until recent versions of Microsoft Access, taking information in a data structure (like an ADO Recordset) and binding it to controls on a form was next to impossible, as well. Around Access 2000 or so, it became possible to bind controls on a form to an open Recordset, making it almost possible to create Access applications that retrieved data from middle-tier business objects. (The implementation isn't perfect, but it's better than nothing.)

The same issues come up when building .NET applications, although almost every method that requires a file name also accepts an in-memory data structure, or some type of stream, from which it can work with data.

Case in point: Recently, a friend was building an application, and he needed to be able to send an email message to a list of recipients with a personalized attachment for each recipient. (No, he's not building a SPAM engine—he's simply building an application that can manage a little mailing list. Really.) The problem is that he didn't want to save each personalized attachment to disk before sending the message, and every technique he found required a file name or a stream when specifying the attachment. He had neither—he had a String instance containing his text. He was well aware that saving each file to disk would cause a serious scalability problem, because he might, at some point, want to host this functionality on a Web site with multiple concurrent users.

There really are two issues here: how to send an email at all from a client application, and once you can do that, how you can add an attachment without first saving the attachment to disk.

Sending Email in .NET
Sending email is simple: in the .NET Framework 2.0, you can use the System.Net.Mail namespace, and its MailMessage and Attachment classes to do the work. In the simplest case, you write code to create a mail message, add an attachment, and send the message. You must fill in all the specific information, including the sender and recipient email addresses, along with the name or IP address of your SMTP server. The code below assumes that you can use your current credentials to authenticate on the SMTP server (this code assumes that you have already added an Imports or using statement for the System.Net.Mail namespace):

[Visual Basic] Dim msg As New MailMessage( _ "Sender@sender.com", _ "Recipient@recipient.com", _ "Subject text here", _ "Body text here") msg.Attachments.Add( _ New Attachment("C:\Myattachment.txt")) Dim client As _ New SmtpClient("Your SMTP Server") client.UseDefaultCredentials = True client.Send(msg) [C#] MailMessage msg = new MailMessage( "Sender@sender.com", "Recipient@recipient.com", "Subject text here", "Body text here"); msg.Attachments.Add( new Attachment( "C:\\Myattachment.txt")); SmtpClient client = new SmtpClient("Your SMTP Server"); client.UseDefaultCredentials = true; client.Send(msg);

If you can't use your current credentials to authenticate on the SMTP server, you can use code like the following to supply the necessary credentials, rather than setting the UseDefaultCredentials property of the SmtpClient class to True. Supply the SmtpClient.Credentials property before calling the Send method:

[Visual Basic] client.Credentials = _ New System.Net.NetworkCredential( _ "username", "password", "domain") [C#] client.Credentials = new System.Net.NetworkCredential( "username", "password", "domain");

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.