Sending Emails in .NET with the System.Net.Mail Namespace
Jim Duffy, Visual Basic MVP, TakeNote Technologies
I recently helped an individual who had taken our Visual Basic and ASP.NET training classes with sending email from the application she was working on. She wanted her website to send high priority, HTML formatted emails along with a couple attachments. In class she had learned the basics of sending emails in .NET but needed a little more help getting things working exactly as she wanted. I figured there are more people like her out there so this article is an extension of my work with her. I have included a complete Visual Studio 2005 project containing all of the source code for this article.
Sending email in .NET 2.0 relies on using the classes contained in the System.Net.Mail namespace. This namespace contains the classes I will be covering in this article.
Class | Description |
MailMessage | Class representing an e-mail message that can be sent using the SmtpClient class |
MailAddress | Class representing an address of an e-mail sender or recipient |
SmtpClient | Class for sending e-mail using the Simple Mail Transfer Protocol |
Attachment | Class representing an attachment to an e-mail |
AlternateView | Class representing the format to view an email message |
LinkedResouce | Class representing an embedded external resource in an email attachment |
In some cases the examples in this article will build on each other. For example, after I cover the section on accessing settings in configuration files, the code will continue to rely on retrieving settings from the configuration files.
Although the sample code in this project is contained in a Windows application, the same code segments will work exactly the same in a web application. The only difference you will encounter between a Windows application and a web application is the name of the configuration file. A Windows application will use app.config and a web application will use web.config. I will cover accessing settings from a configuration file later on in the article.
The Basics
Let’s start simple. Here is the code required to send an email in a Windows, ASP.NET, or Web Service application. I think you’ll agree it’s pretty straightforward.
'Start by creating a mail message object
DimMyMailMessage As New MailMessage( _
"from@fromdomain.com", _
"to@todomain.com ", _
"Message Subject", _
"This is the text for the body of the message")
'Create the SMTPClient object and specify the SMTP server name
Dim SMTPServer As New SmtpClient("mailserver / IP Address here")
SMTPServer.Send(MyMailMessage)
The code opens by creating a MailMessage object and using one of the four available overloads. The sample code makes it pretty clear what the different parameters being passed in are. Next a SmtpClient object is created with the name or IP Address of the mail server. An optional parameter after the mail server is the port number the mail server is listening on. The default is 25. Lastly the SmtpClient’s Send method is called with the MailMessage object being passed in as the parameter. That’s it.
We can expand on the sample code by breaking things out into specific property settings.
'Start by creating a mail message object
DimMyMailMessage As New MailMessage()
‘From requires an instance of the MailAddress type
MyMailMessage.From = New MailAddress("from@fromdomain.com")
'To is a collection of MailAddress types
MyMailMessage.To.Add("to@todomain.com")
MyMailMessage.Subject = "Plain and Simple - Part II"
MyMailMessage.Body = "This is the message text"
'Create the SMTPClient object and specify the SMTP server
Dim SMTPServer As New SmtpClient("mailserver name or IP Address here")
SMTPServer.Send(MyMailMessage)
The MailMessage.From property requires an instance of the MailAddress object be assigned to it. In the initial code sample the From address was automatically converted to a MailAddress object. The MailMessage.To property is a collection of MailAddress objects. Sending an email to multiple recipients is as simple as adding additional addresses to the To collection. So far I have only been working with plain text in the email body. HTML can also be used in email body.
'Start by creating a mail message object
Dim MyMailMessage As New MailMessage()
'From requires an instance of the MailAddress type
MyMailMessage.From = New MailAddress("from@fromdomain.com")
'To is a collection of MailAddress types
MyMailMessage.To.Add("to@todomain.com")
MyMailMessage.Subject = "HTML Content"
MyMailMessage.IsBodyHtml = True
MyMailMessage.Body = "This is the HTML text for the body of the message and this is red."
'Create the SMTPClient object and specify the SMTP server name
Dim SMTPServer As New SmtpClient("mailserver name or IP Address here")
SMTPServer.Send(MyMailMessage)
The IsBodyHTML property determines if the message being sent is HTML or plain text. The default value is false.
What if some of the readers of your email don’t have an email client that can correctly display HTML emails? The good news is that you can send your message as plain text and HTML and let the client automatically select which version to display.
'Start by creating a mail message object
Dim MyMailMessage As New MailMessage()
'From requires an instance of the MailAddress type
MyMailMessage.From = New MailAddress("from@fromdomain.com")
'To is a collection of MailAddress types
MyMailMessage.To.Add("to@todomain.com")
MyMailMessage.Subject = "Plain Text and HTML Content"
'PlainText will be viewable by email clients that do not support HTML
Dim BodyText As String = "This is plain text."
Dim MediaType As String = "text/plain"
Dim PlainText As AlternateView = AlternateView.CreateAlternateViewFromString(BodyText, Nothing, MediaType)
'HTMLContent will be viewable by email clients that support HTML
BodyText = "This is the HTML text for the body of the message and this is red."
MediaType = "text/html"
Dim HTMLContent As AlternateView = AlternateView.CreateAlternateViewFromString(BodyText, Nothing, MediaType)
MyMailMessage.AlternateViews.Add(PlainText)
MyMailMessage.AlternateViews.Add(HTMLContent)
'Create the SMTPClient object and specify the SMTP server
Dim SMTPServer As New SmtpClient("mailserver name or IP Address here")
SMTPServer.Send(MyMailMessage)
The MailMessage.AlternateViews collection contains all of alternate forms of the email message body. In addition to the message body and encoding parameters, the content type (text/HTML or text/plain), is specified in the MediaType property when you create each AlternateView object.
Handling Exceptions
You know as well as I do that things are going to go wrong sometimes. In the case of sending emails things that typically go wrong are network related. What if the mail server is down? What if the network is down?
'Start by creating a mail message object
Dim MyMailMessage As New MailMessage()
'From requires an instance of the MailAddress type
MyMailMessage.From = New MailAddress("from@fromdomain.com")
'To is a collection of MailAddress types
MyMailMessage.To.Add("to@todomain.com")
MyMailMessage.Subject = "Handling Exceptions"
'PlainText will be viewable by email clients that do not support HTML
Dim BodyText As String = "This is plain text."
Dim MediaType As String = "text/plain"
Dim PlainText As AlternateView = AlternateView.CreateAlternateViewFromString(BodyText, Nothing, MediaType)
'HTMLContent will be viewable by email clients that support HTML
BodyText = "This is the HTML text for the body of the message and this is red."
MediaType = "text/html"
Dim HTMLContent As AlternateView = AlternateView.CreateAlternateViewFromString(BodyText, Nothing, MediaType)
MyMailMessage.AlternateViews.Add(PlainText)
MyMailMessage.AlternateViews.Add(HTMLContent)
'Create the SMTPClient object and specify the SMTP server name
Dim SMTPServer As New SmtpClient("mailserver name or IP Address here")
Try
SMTPServer.Send(MyMailMessage)
Catch ex As SmtpException
MessageBox.Show(ex.Message)
EndTry
SmtpException is the exception that is thrown if the SmtpClient object is unable to complete a Send or SendAsync method. I cover the SendAsync method later in the article. There are two other types of exceptions, SmtpFailedRecipientException and SmtpFailedRecipientsException that could be thrown when an email cannot be delivered to the recipient or recipients.
Using Display Name
So far all the emails I have sent will display the email address used for the From and To in the email client. I would rather have the individual’s name displayed instead.
'Start by creating a mail message object
Dim MyMailMessage As New MailMessage()
'From requires an instance of the MailAddress type
MyMailMessage.From = New MailAddress("from@from.com", "From Name")
'To is a collection of MailAddress types
MyMailMessage.To.Add(New MailAddress("to@todomain.com”, "To Name"))
MyMailMessage.CC.Add(New MailAddress("cc@ccdomain.com”, "CC Name"))
MyMailMessage.Bcc.Add(New MailAddress("bcc@bccdomain.com”, "BCC Name"))
MyMailMessage.Subject = "Display Name"
MyMailMessage.Body = "This is the message text"
Dim SMTPServer As New SmtpClient("mailserver name or IP Address here")
Try
SMTPServer.Send(MyMailMessage)
Catch ex As SmtpException
MessageBox.Show(ex.Message)
EndTry
I threw a few things in this time. Notice that to take advantage of the Display Name capability I had to create a MailAddress object while adding it to the To collection. The second parameter is the name that will be displayed in the email client. I also show code for adding recipients in the cc and bcc collections.
Adding additional MailAddress objects to the To, CC, and BCC collections results in the email being sent to all the email addresses in the collections.
'Start by creating a mail message object
Dim MyMailMessage As New MailMessage()
'From requires an instance of the MailAddress type
MyMailMessage.From = New MailAddress("from@from.com", "From Name")
'To is a collection of MailAddress types
MyMailMessage.To.Add(New MailAddress("to1@todomain.com”, "To 1 Name"))
MyMailMessage.To.Add(New MailAddress("to2@todomain.com”, "To 2 Name"))
MyMailMessage.Subject = "More than one"
MyMailMessage.IsBodyHtml = True
MyMailMessage.Body = "This is the HTML text for the body of the message and this is red."
'Create the SMTPClient object and specify the SMTP server name
Dim SMTPServer As New SmtpClient("mailserver name or IP Address here")
Try
SMTPServer.Send(MyMailMessage)
Catch ex As SmtpException
MessageBox.Show(ex.Message)
EndTry
Specifying the Reply To Address
You can specify the email address that is used if the recipient replies to the email.
'Start by creating a mail message object
Dim MyMailMessage As New MailMessage()
'From requires an instance of the MailAddress type
MyMailMessage.From = New MailAddress("from@from.com", "From Name")
'To is a collection of MailAddress types
MyMailMessage.To.Add(New MailAddress("to1@todomain.com”, "To 1 Name"))
MyMailMessage.Subject = "Reply To"
MyMailMessage.Body = "This is the message text"
MyMailMessage.ReplyTo = New MailAddress("replyTo@replyTo.com")
'Create the SMTPClient object and specify the SMTP server name
Dim SMTPServer As New SmtpClient("mailserver name or IP Address here")
Try
SMTPServer.Send(MyMailMessage)
Catch ex As SmtpException
MessageBox.Show(ex.Message)
EndTry
The MailMessage.ReplyTo property determines the email address that automatically populates the To line if the recipient decides to reply to the email they received.
Setting Message Priority
Being the important person that you are, of course all the emails you send needs to be of the highest priority. Ok, well, maybe not but you can specify the message priority for the email being sent.
'Start by creating a mail message object
Dim MyMailMessage As New MailMessage()
'From requires an instance of the MailAddress type
MyMailMessage.From = New MailAddress("from@fromdomain.com")
'To is a collection of MailAddress types
MyMailMessage.To.Add(New MailAddress("to1@todomain.com”, "To 1 Name"))
MyMailMessage.Subject = "High Priority!!"
MyMailMessage.Body = "This is the message text"
'Priority being assigned
MyMailMessage.Priority = MailPriority.Low
MyMailMessage.Priority = MailPriority.Normal
MyMailMessage.Priority = MailPriority.High
'Create the SMTPClient object and specify the SMTP server name
Dim SMTPServer As New SmtpClient("mailserver name or IP Address here")
Try
SMTPServer.Send(MyMailMessage)
Catch ex As SmtpException
MessageBox.Show(ex.Message)
EndTry
Message priority is specified by assigning the MailMessage.Priority property one of the values in the MailPriority enum. I’ve included them all in the code sample above for reference. The email above will be sent with a High priority.
Requesting a Return Receipt
I know I have gotten my fair share of emails that came with a Return Receipt request. You can specify that your emails are sent with a return receipt as well.
'Start by creating a mail message object
Dim MyMailMessage As New MailMessage()
'From requires an instance of the MailAddress type
MyMailMessage.From = New MailAddress("from@from.com", "From Name")
'To is a collection of MailAddress types
MyMailMessage.To.Add(New MailAddress("to1@todomain.com”, "To 1 Name"))
MyMailMessage.Subject = "Return Receipt Requested"
MyMailMessage.Body = "This is the message text"
'Add a custom header named Disposition-Notification-To and specify the
'read recept address
MyMailMessage.Headers.Add("Disposition-Notification-To", "returnreceipt@return.com")
'Create the SMTPClient object and specify the SMTP server name
Dim SMTPServer As New SmtpClient("mailserver name or IP Address here")
Try
SMTPServer.Send(MyMailMessage)
Catch ex As SmtpException
MessageBox.Show(ex.Message)
EndTry
Adding a return receipt is accomplished by adding a custom header to the MailMessage.Headers collection. Specify Disposition-Notification-To as the first parameter and the email address the return receipt should be sent to as the second parameter when adding the item to the Headers collection and you’re good to go.
Adding Custom Headers
If you take a closer look at the details of an email you may see a number lines starting with X- in the email header. While some of these have specific values, you can add your own custom header information as well. You could throw the name of the current user, the name of the computer, or any other type of information you may want to capture.
'Start by creating a mail message object
Dim MyMailMessage As New MailMessage()
'From requires an instance of the MailAddress type
MyMailMessage.From = New MailAddress("from@from.com", "From Name")
'To is a collection of MailAddress types
MyMailMessage.To.Add(New MailAddress("to1@todomain.com”, "To 1 Name"))
MyMailMessage.Subject = "Custom Header Information Inserted"
MyMailMessage.Body = "This is the message text"
'Add custom headers named X-Company and X-ComputerName and add them to the message
MyMailMessage.Headers.Add("X-Company", "TakeNote Technologies")
MyMailMessage.Headers.Add("X-ComputerName", My.Computer.Name)
'Create the SMTPClient object and specify the SMTP server name
Dim SMTPServer As New SmtpClient("mailserver name or IP Address here")
Try
SMTPServer.Send(MyMailMessage)
Catch ex As SmtpException
MessageBox.Show(ex.Message)
EndTry
Just like the code in the previous section, adding custom headers is accomplished by adding an item to the MailMessage.Headers collection. In the code above I added two custom header items, one named X-Company which contains the name of my company another named X-ComputerName which contains the name of the machine the email was generated from.
Sending Attachments
Very often sending information the body of an email just isn’t enough. One or more attachments may be necessary to fully communicate the entire message of the email.
'Start by creating a mail message object
Dim MyMailMessage As New MailMessage()
'From requires an instance of the MailAddress type
MyMailMessage.From = New MailAddress("from@from.com", "From Name")
'To is a collection of MailAddress types
MyMailMessage.To.Add(New MailAddress("to1@todomain.com”, "To 1 Name"))
MyMailMessage.Subject = "Attachements Included"
MyMailMessage.Body = "This is the message text"
'Add an attachment to your message simply add a new Attachment object to the Attachments collection
MyMailMessage.Attachments.Add(New Attachment("article.txt"))
MyMailMessage.Attachments.Add(New Attachment("article.docx"))
MyMailMessage.Attachments.Add(New Attachment("TakeNote.gif"))
'Create the SMTPClient object and specify the SMTP server name
Dim SMTPServer As New SmtpClient("mailserver name or IP Address here")
Try
SMTPServer.Send(MyMailMessage)
Catch ex As SmtpException
MessageBox.Show(ex.Message)
EndTry
Attachments are added to an email message by adding a new Attachment object to the MailMessage.Attachments collection.
Reading Setting from Configuration Files
So far all of the code samples have explicitly set the properties required to send an email. What if things changed over time, say you want to use a different mail server or change the email address the emails are sent from. Up to now you would have to make the change in your code, recompile, and re-distribute. That’s not good. Enter the world of the configuration file. In Windows applications I’m referring to app.config and with web applications I’m referring to web.config.
In the configuration file you can specify a number of settings including the default from address, the default mail sever, the port number the mail server listens to, and authentication credentials.
< configuration >
< system.net >
< mailSettings >
< smtp from =" from@from.com">
< network
host =" mail server here"
defaultCredentials =" true"
port =" 25"
/>
</ smtp >
</ mailSettings >
</ system.net >
Above is a piece of a configuration file specifying a number of different settings. In order for these settings to be used you just omit the code that explicitly sets these values and the default settings from the config file will be used.
'Start by creating a mail message object
Dim MyMailMessage As New MailMessage()
'From being pulled from config file
'To is a collection of MailAddress types
MyMailMessage.To.Add(New MailAddress("to1@todomain.com”, "To 1 Name"))
MyMailMessage.Subject = "Configuration Settings"
MyMailMessage.Body = "This is the message text"
'Create the SMTPClient object and DO NOT specify the SMTP server name
Dim SMTPServer As New SmtpClient()
Try
SMTPServer.Send(MyMailMessage)
Catch ex As SmtpException
MessageBox.Show(ex.Message)
EndTry
Notice in the above code that explicitly set the MailMessage.From property has been omitted and the name of the mail server has been omitted from the line that creates the SMTPServer object. Those two values will be picked up from the configuration file.
Embedding Image in Message
Sometimes you may want to embed an image in the text you’re creating for the body of the email message. This is accomplished by adding an item to the LinkedResources collection and referencing its cid in the body of the email.
'Start by creating a mail message object
Dim MyMailMessage As New MailMessage()
'From being pulled from config file
'To is a collection of MailAddress types
MyMailMessage.To.Add(New MailAddress("to1@todomain.com”, "To 1 Name"))
MyMailMessage.Subject = "Linked Resource"
'HTMLContent will be viewable by email clients that support HTML
Dim BodyText As String = "This is my company's logo:
https://www.takenote.com"
Dim MediaType As String = "text/html"
Dim HTMLContent As AlternateView = AlternateView.CreateAlternateViewFromString(BodyText, Nothing, MediaType)
'create the LinkedResource (embedded image)
Dim CompanyLogo As New LinkedResource("D:\temp\TakeNote.gif")
CompanyLogo.ContentId = "TNTlogo"
'add the LinkedResource to the appropriate view
HTMLContent.LinkedResources.Add(CompanyLogo)
MyMailMessage.AlternateViews.Add(HTMLContent)
'Create the SMTPClient object and DO NOT specify the SMTP server name
Dim SMTPServer As New SmtpClient()
Try
SMTPServer.Send(MyMailMessage)
Catch ex As SmtpException
MessageBox.Show(ex.Message)
EndTry
The BodyText variable contains the HTML for the body of the message. Embedded in the HTML is an tag with the cid equal to the ContentID of the LinkedResource. The CompanyLogo object is created and is of type LinkedResource. I then set its ContentID set to TNTLogo. Next the CompanyLogo LinkedResource object is added to the HTMLContent.LinkedResouces collection. The HTMLContent AlternateView object is then added to the MailMessage.AlternateViews collection.
Delivery Methods
One of the properties on the SMTPServer object determines if the email will be immediately sent via the network connection or if an .EML email file will be dropped in a folder and wait to be picked up by IIS to be sent.
'Start by creating a mail message object
Dim MyMailMessage As New MailMessage()
'From being pulled from config file
'To is a collection of MailAddress types
MyMailMessage.To.Add(New MailAddress("to1@todomain.com”, "To 1 Name"))
MyMailMessage.Subject = "Pick me up!"
MyMailMessage.Body = "This is the message text"
'Create the SMTPClient object and DO NOT specify the SMTP server name
Dim SMTPServer As New SmtpClient()
SMTPServer.DeliveryMethod = SmtpDeliveryMethod.PickupDirectoryFromIis
Try
SMTPServer.Send(MyMailMessage)
Catch ex As SmtpException
MessageBox.Show(ex.Message)
EndTry
The values available in the SmtpDelieveryMethod enum are Network (the default), PickupDirectoryFromIIS, and SpecifiedPickupDirectory. In this sample code an email file (.EML) is dropped in the default location where IIS looks for emails to send (C:\Inetpub\mailroot\Pickup).
Using Delivery Notification
Delivery Notification, not to be confused with requesting a Return Receipt, provides the option of having an email sent to the from email address based on the delivery success or failure of the email.
'Start by creating a mail message object
Dim MyMailMessage As New MailMessage()
'From being pulled from config file
'To is a collection of MailAddress types
MyMailMessage.To.Add(New MailAddress("to1@todomain.com”, "To 1 Name"))
MyMailMessage.Subject = "Delivery Notification"
MyMailMessage.Body = "This is the message text"
'Sends a message to from if email is not deliverable
MyMailMessage.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure
'Create the SMTPClient object and DO NOT specify the SMTP server name, it’s being pulled from config file
Dim SMTPServer As New SmtpClient()
SMTPServer.DeliveryMethod = SmtpDeliveryMethod.PickupDirectoryFromIis
Try
SMTPServer.Send(MyMailMessage)
Catch ex As SmtpException
MessageBox.Show(ex.Message)
EndTry
In this sample code an email will be sent to the From address specified in the configuration file if the email is not successfully sent.
Sending Email With SSL
Sending email via a Secure Sockets Layer (SSL) connection is a simple matter of setting a property.
'Start by creating a mail message object
Dim MyMailMessage As New MailMessage()
'From being pulled from config file
'To is a collection of MailAddress types
MyMailMessage.To.Add(New MailAddress("to1@todomain.com", "To 1 Name"))
MyMailMessage.Subject = "SSL Email"
MyMailMessage.Body = "This is the message text"
'Create the SMTPClient object and DO NOT specify the SMTP server name
Dim SMTPServer As New SmtpClient()
'Enable SSL does not work in tandem with SmtpDeliveryMethod.PickupDirectoryFromIis
SMTPServer.DeliveryMethod = SmtpDeliveryMethod.Network
SMTPServer.EnableSsl = True
Try
SMTPServer.Send(MyMailMessage)
Catch ex As SmtpException
MessageBox.Show(ex.Message)
EndTry
The SmtpClient.EnableSsl property determines if the email should be sent via a SSL connection.
Authentication
If your IIS mail server has been configured to use Basic Authentication then a userName and password values need to be supplied when sending the message.
'Start by creating a mail message object
Dim MyMailMessage As New MailMessage()
'From being pulled from config file
'To is a collection of MailAddress types
MyMailMessage.To.Add(New MailAddress("to1@todomain.com”, "To 1 Name"))
MyMailMessage.Subject = "Authentication Email"
MyMailMessage.Body = "This is the message text"
'Create the SMTPClient object and DO NOT specify the SMTP server name
Dim SMTPServer As New SmtpClient()
'The userName and password can be explicity set or pulled from config file
'SMTPServer.Credentials = New NetworkCredential("jim", "secret")
Try
SMTPServer.Send(MyMailMessage)
Catch ex As SmtpException
MessageBox.Show(ex.Message)
EndTry
In this code sample the credentials are not explicitly set. They are retrieved from a configuration file that looks like one below.
< configuration >
< system.net >
< mailSettings >
< smtp from =" from@from.com">
< network
host =" mail server name or IP here"
userName =" jim"
password =" secret"
defaultCredentials =" false"
port =" 25"
/>
</ smtp >
</ mailSettings >
</ system.net >
Sending Email Asynchronously
Up until now all of the emails being sent in this article have been sent synchronously using the SMTPServer.Send() method. That means that any subsequent code has to wait until the email delivery process has completed. It doesn’t have to be that way though. The SMTPServer.SendAsync() method provides a way to send an email and have the code after the email delivery process continue executing without having to wait for the process to complete.
Private Sub btnASync_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnASync.Click
'Start by creating a mail message object
Dim MyMailMessage As New MailMessage()
'From being pulled from config file
'To is a collection of MailAddress types
MyMailMessage.To.Add(New MailAddress("to1@todomain.com”, "To 1 Name"))
MyMailMessage.Subject = "Async Email"
MyMailMessage.Body = "This is the message text"
'Create the SMTPClient object and DO NOT specify the SMTP server name
Dim SMTPServer As New SmtpClient()
'the UserState object can be accessed in OnCompleted event handler via e.UserState
Dim UserState As Object = MyMailMessage
'Add an event handler for when the Async send completes
AddHandler SMTPServer.SendCompleted, AddressOf SMTPServer_OnCompleted
SMTPServer.SendAsync(MyMailMessage, UserState)
'You could cancel a SendAsync call with SendAsyncCancel
'SMTPServer.SendAsyncCancel()
End Sub
Public Sub SMTPServer_OnCompleted(ByVal sender AsObject, ByVal e As AsyncCompletedEventArgs)
'Get a reference to the Original MailMessage object
Dim CompletedMailMessage As MailMessage = CType(e.UserState, MailMessage)
'Get information about the email being sent
Dim EmailFrom As String = CompletedMailMessage.From.Address
Dim EmailSubject As String = CompletedMailMessage.Subject
'Was the async operation cancelled?
If e.Cancelled Then
Console.WriteLine("SendAsync email from {0} regarding {1} was canceled.", EmailFrom, EmailSubject)
ExitSub
EndIf
If e.Error Is Nothing Then
'Email sent successfully
Console.WriteLine("SendAsync email from {0} regarding {1} was sent.", EmailFrom, EmailSubject)
Else
'Trap and handle the problem here
Console.WriteLine("SendAsync email from {0} regarding {1} was *NOT* sent.", EmailFrom, EmailSubject)
EndIf
End Sub
There are two key lines of code for sending email asynchronously, the AddHandler line and the actual call to the SMTPServer.SendAsync. The SMTPServer_OnCompleted method is executed when the email operation completes. In the SMTPServer_OnCompleted method e.UserState refers to the UserState object passed into the SMTPServer.SendAsync method. Since I assigned MyMailMessage to the UserState object in the initial procedure I have access to all of the information about the MailMessage in the SMTPServer_OnCompleted method. In the SMTPServer_OnCompleted method I check the value in e.Cancelled to see if the operation had been cancelled by a call to the SMTPServer.SendAsyncCancel method. If the operation wasn’t cancelled then I check to see if an error object was passed in as an AsyncCompletedEventArgs member. If it wasn’t then I know the email was sent successfully.
Summary
Well that wraps up this look at sending email using the tools available within the System.Net.Mail namespace. For information on setting up an SMTP server see SMTP Server Setup on TechNet. Happy emailing!
About Jim Duffy
Jim Duffy is a Microsoft MVP, INETA Speaker, radio show co-host, former DotNetNuke Core Team member, and the founder and president of TakeNote Technologies (www.takenote.com ). TakeNote, a Microsoft Partner and a Developer's Choice Award winner for its hands-on training classes, specializes in .NET developer training and helping clients create business solutions with Microsoft enterprise technologies. Jim is a popular conference and user group speaker due to his knowledge, humor, and quick-witted approach. He is an exceptional trainer, skilled developer, and has been published in a number of leading publications including CoDe Magazine (www.code-magazine.com ). Jim's background also includes a Bachelors degree in Computer and Information Systems and over 20 years of programming and training experience. Jim is co-host of Computers 2K7, a weekly call in radio show (AM 850 The Buzz) in Raleigh, NC.