The System.Net.Mail namespace defined in the System.dll assembly contains all the classes used to send e-mails. The older System.Web.Mail namespace, and its related classes, that were used with ASP.NET 1.x are still there, but its use has been deprecated now in favor of these new classes in ASP.NET 2.0 that provide more features. The principal classes are MailMessage, which represents an e-mail message, and the SmtpClient class, which provides the methods used to send a MailMessage by connecting to a configured SMTP server (SMTP is the Simple Mail Transfer Protocol, which is the low-level protocol used by Microsoft Exchange and other mail servers).
MailMessage fully describes an e-mail message, with its subject, body (in plain-text, HTML, or in both formats), the To, CC, and BCC addresses, and any attachments that might be used. The simplest way to create an e-mail is using the MailMessage constructor, which takes the sender’s address, the recipient’s address, the mail’s subject, and the body, as shown below:
MailMessage mail = new MailMessage(
"from@somewhere.com", "to@somewhere.com", "subject", "body");
However, this approach will be too limited in most cases, because you may want to specify the sender’s display name in addition to his e-mail address (the display name is what is displayed by the mail client, if present, instead of the address, and makes the mail and its sender look more professional). You may also want to send to more than one recipient, use an a HTML body (as an alternative, or in addition, to the plain-text version), include some attachments, use a different encoding, modify the mail’s priority, and so on. All these settings, and more, are specified by means of a number of instance properties of the MailMessage class. Their names should be self-explanatory, and some examples include the following: Subject, Body, IsBodyHtml, From, To, CC, Bcc, BodyEncoding, Attachments, AlternateViews, Headers, Priority, and ReplyTo. The class’ constructor enables you to specify a From property of type MailAddress, Address, and UserName properties. The To, CC, and Bcc properties are of type MailAddressCollection, and thus can accept multiple MailAddress instances (you can add them by means of the collection’s Add method). Similarly, the MailMessage’s Attachments property is of type AttachmentCollection, a collection of Attachment instances that point to files located on the server. The following example shows how to build a HTML-formatted e-mail message that will be sent to multiple recipients, with high priority, and that includes a couple of attachments:
// create the message
MailMessage mail = new MailMessage();
// set the sender's address and display name
mail.From = new MailAddress("mbellinaso@wrox.com", "Marco Bellinaso");
// add a first recipient by specifying only her address
mail.To.Add("john@wroxfans.com");
// add a second recipient by specifying her address and display name
mail.To.Add(new MailAddress("anne@wroxfans.com", "Anne Gentle"));
// add a third recipient, but to the CC field this time
mail.CC.Add("mike@wroxfans.com");
// set the mail's subject and HTML body
mail.Subject = "Sample Mail";
mail.Body = "Hello, <b>my friend</b>!<br />How are you?";
mail.IsBodyHtml = true;
// set the mail’s priority to high
mail.Priority = MailPriority.High;
// add a couple of attachments
mail.Attachments.Add(
new Attachment(@"c:\demo.zip", MediaTypeNames.Application.Octet));
new Attachment(@"c:\report.xls", MediaTypeNames.Application.Octet));
If you also wanted to provide a plain-text version of the body in the same mail, so that the display format (plain text or HTML) would depend on the user’s e-mail client settings, you would add the following lines:
string body = "Hello, my friend!\nHow are you?";
AlternateView plainView = new AlternateView(body, MediaTypeNames.Text.Plain);
mail.AlternateViews.Add(plainView);
Once a MailMessage object is ready, the e-mail message it describes can be sent out by means of the Send method of the SmtpClient class, as shown here:
SmtpClient smtpClient = new SmtpClient();
smtpClient.Send(mail);
Before calling the Send method, you may need to set some configuration settings, such as the SMTP server’s address (the SmtpClient’s Host property), port (the Port property) and its credentials (the Credentials property), whether the connection in encrypted with SSL (the EnableSsl property), and the timeout in milliseconds for sending the mail (the Timeout property, which defaults to 100 seconds). An important property is DeliveryMethod, which defines how the mail message is delivered. It’s of type SmtpDeliveryMethod, an enumeration with the following values:
The delivery method you choose can dramatically change the performance of your site when sending many e-mails, and can produce different errors during the send operation. If you select the Network delivery method, the SmtpClient class takes care of sending the mail directly, and raises an error if the destination e-mail address is not found or if there are other transmission problems. With the other two methods, instead of sending the message directly, an EML mail file is prepared and saved to the file system, where another application (IIS or something else) will pick them up later for the actual delivery (a queue accumulates the messages, which means the web application will not have to wait for each message to be sent over the Internet). However, when using the second and third delivery methods, your web application cannot be notified of any errors that may occur during transmission of the message, and it will be up to IIS (or another mail agent that might be used) to handle them. In general, the PickupDirectoryFromIis method is the preferred one, unless your ASP.NET application is not given the right to write to IIS mail folders (check with your web hosting provider service if you don’t use your own servers).
If you set all SmtpClient properties mentioned above directly in your C# code, you’ll have to recompile the application or edit the source file every time you want to change any of these settings. This, of course, is not an option if you’re selling a packaged application, or you want to let the administrator change these settings on his own without directly involving you. As an alternative to hard-coding the delivery method, you can set it declaratively in the web.config file, which now supports a new configuration section named <mailSettings>, located under <system.net>, which allows you to specify delivery settings. The SmtpClient class automatically loads those settings from web.config to configure itself at runtime, so you should generally not set your delivery and SMTP options directly in your C# code. Following is an extract of the configuration file that shows how to select PickupDirectoryFromIis as the delivery method, set up the sender’s e-mail address and the SMTP server’s name (or IP address) and port, and specify that you want to use the default credentials to connect to the server:
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<system.net>
<mailSettings>
<smtp deliveryMethod="PickupDirectoryFromIis"
from="mbellinaso@wrox.com">
<network defaultCredentials="true"
host="vmwin2003" port="25"></network>
</smtp>
</mailSettings>
</system.net>
<!-- other configuration sections... -->
</configuration>
The SmtpClient’s Send method used in the preceding code snippet sends the e-mail synchronously, which means that the task must complete before the execution of your application can resume. The term synchronous means “do what I asked, and I’ll stop and wait for you to finish,” and the term asynchronous means “do what I asked, but let me continue doing other work, and you should notify me when you’re done.” The SmtpClient class also has a SendAsync method to send the mail asynchronously. It returns immediately, and the e-mail is prepared and sent out on a separate thread. When the send task is complete, the SmtpClient’s SendCompleted event is raised. This event is also raised in case of errors, and the Error and Cancelled properties of its second argument (of type AsyncCompletedEventArgs) tells you whether it was raised because the send was cancelled, because there was an error, or because the send completed successfully. Here’s a sample snippet that shows how to send the mail asynchronously, and handle the resulting completion event:
smtpClient.SendCompleted += new SendCompletedEventHandler(MailSendCompleted);
smtpClient.SendAsync(message, null);
...
public static void MailSendCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Cancelled)
Trace.Write("Send canceled.");
if (e.Error != null)
Trace.Write(e.Error.ToString());
else
Trace.Write("Message sent.");
}
An asynchronous send operation can be cancelled before completion by calling the SmtpClient’s SendAsyncCancel method. Note that you can’t send a second e-mail while a SmtpClient has another send in progress; if you try to do so, you’ll receive an InvalidOperationException.
Remember Me
Powered by: newtelligence dasBlog 1.8.5223.1