该文章属于http://www.systemnetmail.com/default.aspx关于System.Net.Mail的一部分。
英文不难,所以我也就没翻译了。
文章的地址为:http://www.systemnetmail.com/faq/4.aspx
How do I read SMTP configuration data?
Using special settings in your app's configuration file, System.Net.Mail can configure itself.
Using the configuation file, you can set the following default properties:
MailMessage.From
SmtpClient.Host
SmtpClient.Port
The settings will also allow you specify a Username and Password to be used for authentication. It is important to note that if DefaultCredentials are specified to true, the userName and password attributes are igorned.
Here is an example of the <mailSettings> node:
- <configuration>
- <system.net>
- <mailSettings>
- <smtp from="me@mycompany.com">
- <!--
- The <network> node supports the following properties, but we won't use all of them
- <network host="127.0.0.1" port="25" userName="myUserName" password="secret" defaultCredentials="true" />
- -->
- <network host="127.0.0.1" />
- </smtp>
- </mailSettings>
- </system.net>
- </configuration>
How do I create a log file of the SMTP session?
The System.Net namespace allows you to log the contents of the SMTP session to a file. This is done through a combination of trace switches in your app's configuration file.
The following example of trace switches will cause the SMTP session to be logged to a file named "System.Net.trace.log".
- <configuration>
- <system.diagnostics>
- <trace autoflush="true" />
- <sources>
- <source name="System.Net" >
- <listeners>
- <add name="MyTraceFile"/>
- </listeners>
- </source>
- <source name="System.Net.Sockets">
- <listeners>
- <add name="MyTraceFile"/>
- </listeners>
- </source>
- </sources>
- <sharedListeners>
- <add
- name="MyTraceFile"
- type="System.Diagnostics.TextWriterTraceListener"
- initializeData="System.Net.trace.log" />
- </sharedListeners>
- <switches>
- <add name="System.Net" value="Verbose" />
- <add name="System.Net.Sockets" value="Verbose" />
- </switches>
- </configuration>
Here is what the log file might look like:
System.Net Verbose: 0 : [0992] SmtpClient::.ctor(host=127.0.0.1) System.Net Information: 0 : [0992] Associating SmtpClient#47606018 with SmtpTransport#5689696 System.Net Verbose: 0 : [0992] Exiting SmtpClient::.ctor() -> SmtpClient#47606018 System.Net Verbose: 0 : [0992] SmtpClient#47606018::Send(MailMessage#5138334) System.Net Information: 0 : [0992] SmtpClient#47606018::Send(DeliveryMethod=Network) System.Net Information: 0 : [0992] Associating SmtpClient#47606018 with MailMessage#5138334 System.Net Information: 0 : [0992] Associating SmtpTransport#5689696 with SmtpConnection#31950948 System.Net Information: 0 : [0992] Associating SmtpConnection#31950948 with ServicePoint#34920472 System.Net.Sockets Verbose: 0 : [0992] Socket#22453229::Socket(InterNetwork#2) System.Net.Sockets Verbose: 0 : [0992] Exiting Socket#22453229::Socket() System.Net.Sockets Verbose: 0 : [0992] Socket#22453229::Connect(1:25#16777318) System.Net.Sockets Verbose: 0 : [0992] Exiting Socket#22453229::Connect() System.Net Information: 0 : [0992] Associating SmtpConnection#31950948 with SmtpPooledStream#48167163 System.Net.Sockets Verbose: 0 : [0992] Socket#22453229::Receive() System.Net.Sockets Verbose: 0 : [0992] Data from Socket#22453229::Receive System.Net.Sockets Verbose: 0 : [0992] 00000000 : 32 32 30 20 77 32 6B 20-4D 69 63 72 6F 73 6F 66 : 220 w2k Microsof System.Net.Sockets Verbose: 0 : [0992] 00000010 : 74 20 45 53 4D 54 50 20-4D 41 49 4C 20 53 65 72 : t ESMTP MAIL Ser System.Net.Sockets Verbose: 0 : [0992] 00000020 : 76 69 63 65 2C 20 56 65-72 73 69 6F 6E 3A 20 35 : vice, Version: 5 System.Net.Sockets Verbose: 0 : [0992] 00000030 : 2E 30 2E 32 31 39 35 2E-36 37 31 33 20 72 65 61 : .0.2195.6713 rea System.Net.Sockets Verbose: 0 : [0992] 00000040 : 64 79 20 61 74 20 20 53-61 74 2C 20 33 31 20 44 : dy at Sat, 31 D System.Net.Sockets Verbose: 0 : [0992] 00000050 : 65 63 20 32 30 30 35 20-32 32 3A 31 33 3A 31 34 : ec 2005 22:13:14 System.Net.Sockets Verbose: 0 : [0992] 00000060 : 20 2D 30 36 30 30 20 0D-0A : -0600 .. System.Net.Sockets Verbose: 0 : [0992] Exiting Socket#22453229::Receive() -> 105#105 System.Net.Sockets Verbose: 0 : [0992] Socket#22453229::Send() System.Net.Sockets Verbose: 0 : [0992] Data from Socket#22453229::Send System.Net.Sockets Verbose: 0 : [0992] 00000000 : 45 48 4C 4F 20 77 32 6B-0D 0A : EHLO w2k.. System.Net.Sockets Verbose: 0 : [0992] Exiting Socket#22453229::Send() -> 10#10 System.Net.Sockets Verbose: 0 : [0992] Socket#22453229::Receive() System.Net.Sockets Verbose: 0 : [0992] Data from Socket#22453229::Receive System.Net.Sockets Verbose: 0 : [0992] 00000000 : 32 35 30 2D 77 32 6B 20-48 65 6C 6C 6F 20 5B 31 : 250-w2k Hello [1 System.Net.Sockets Verbose: 0 : [0992] 00000010 : 32 37 2E 30 2E 30 2E 31-5D 0D 0A 32 35 30 2D 41 : 27.0.0.1]..250-A System.Net.Sockets Verbose: 0 : [0992] 00000020 : 55 54 48 20 47 53 53 41-50 49 20 4E 54 4C 4D 20 : UTH GSSAPI NTLM System.Net.Sockets Verbose: 0 : [0992] 00000030 : 4C 4F 47 49 4E 0D 0A 32-35 30 2D 41 55 54 48 3D : LOGIN..250-AUTH= System.Net.Sockets Verbose: 0 : [0992] 00000040 : 4C 4F 47 49 4E 0D 0A 32-35 30 2D 54 55 52 4E 0D : LOGIN..250-TURN. System.Net.Sockets Verbose: 0 : [0992] 00000050 : 0A 32 35 30 2D 41 54 52-4E 0D 0A 32 35 30 2D 53 : .250-ATRN..250-S System.Net.Sockets Verbose: 0 : [0992] 00000060 : 49 5A 45 20 32 30 39 37-31 35 32 0D 0A 32 35 30 : IZE 2097152..250 System.Net.Sockets Verbose: 0 : [0992] 00000070 : 2D 45 54 52 4E 0D 0A 32-35 30 2D 50 49 50 45 4C : -ETRN..250-PIPEL System.Net.Sockets Verbose: 0 : [0992] 00000080 : 49 4E 49 4E 47 0D 0A 32-35 30 2D 44 53 4E 0D 0A : INING..250-DSN.. System.Net.Sockets Verbose: 0 : [0992] 00000090 : 32 35 30 2D 45 4E 48 41-4E 43 45 44 53 54 41 54 : 250-ENHANCEDSTAT System.Net.Sockets Verbose: 0 : [0992] 000000A0 : 55 53 43 4F 44 45 53 0D-0A 32 35 30 2D 38 62 69 : USCODES..250-8bi System.Net.Sockets Verbose: 0 : [0992] 000000B0 : 74 6D 69 6D 65 0D 0A 32-35 30 2D 42 49 4E 41 52 : tmime..250-BINAR System.Net.Sockets Verbose: 0 : [0992] 000000C0 : 59 4D 49 4D 45 0D 0A 32-35 30 2D 43 48 55 4E 4B : YMIME..250-CHUNK System.Net.Sockets Verbose: 0 : [0992] 000000D0 : 49 4E 47 0D 0A 32 35 30-2D 56 52 46 59 0D 0A 32 : ING..250-VRFY..2 System.Net.Sockets Verbose: 0 : [0992] 000000E0 : 35 30 20 4F 4B 0D 0A : 50 OK.. System.Net.Sockets Verbose: 0 : [0992] Exiting Socket#22453229::Receive() -> 231#231 System.Net.Sockets Verbose: 0 : [0992] Socket#22453229::Send() System.Net.Sockets Verbose: 0 : [0992] Data from Socket#22453229::Send System.Net.Sockets Verbose: 0 : [0992] 00000000 : 4D 41 49 4C 20 46 52 4F-4D 3A 3C 6D 65 40 6D 79 : MAIL FROM: .. System.Net.Sockets Verbose: 0 : [0992] Exiting Socket#22453229::Send() -> 30#30 System.Net.Sockets Verbose: 0 : [0992] Socket#22453229::Receive() System.Net.Sockets Verbose: 0 : [0992] Data from Socket#22453229::Receive System.Net.Sockets Verbose: 0 : [0992] 00000000 : 32 35 30 20 32 2E 31 2E-30 20 6D 65 40 6D 79 63 : 250 2.1.0 me@myc System.Net.Sockets Verbose: 0 : [0992] 00000010 : 6F 6D 70 61 6E 79 2E 63-6F 6D 2E 2E 2E 2E 53 65 : ompany.com....Se System.Net.Sockets Verbose: 0 : [0992] 00000020 : 6E 64 65 72 20 4F 4B 0D-0A : nder OK.. System.Net.Sockets Verbose: 0 : [0992] Exiting Socket#22453229::Receive() -> 41#41 System.Net.Sockets Verbose: 0 : [0992] Socket#22453229::Send() System.Net.Sockets Verbose: 0 : [0992] Data from Socket#22453229::Send System.Net.Sockets Verbose: 0 : [0992] 00000000 : 52 43 50 54 20 54 4F 3A-3C 68 69 6D 40 68 69 73 : RCPT TO: .. System.Net.Sockets Verbose: 0 : [0992] Exiting Socket#22453229::Send() -> 30#30 System.Net.Sockets Verbose: 0 : [0992] Socket#22453229::Receive() System.Net.Sockets Verbose: 0 : [0992] Data from Socket#22453229::Receive System.Net.Sockets Verbose: 0 : [0992] 00000000 : 35 35 30 20 35 2E 37 2E-31 20 55 6E 61 62 6C 65 : 550 5.7.1 Unable System.Net.Sockets Verbose: 0 : [0992] 00000010 : 20 74 6F 20 72 65 6C 61-79 20 66 6F 72 20 68 69 : to relay for hi System.Net.Sockets Verbose: 0 : [0992] 00000020 : 6D 40 68 69 73 63 6F 6D-70 61 6E 79 2E 63 6F 6D : m@hiscompany.com System.Net.Sockets Verbose: 0 : [0992] 00000030 : 0D 0A : .. System.Net.Sockets Verbose: 0 : [0992] Exiting Socket#22453229::Receive() -> 50#50 System.Net Error: 0 : [0992] Exception in the SmtpClient#47606018::Send - Mailbox unavailable. The server response was: 5.7.1 Unable to relay for him@hiscompany.com System.Net Error: 0 : [0992] at System.Net.Mail.SmtpTransport.SendMail(MailAddress sender, MailAddressCollection recipients, String deliveryNotify, SmtpFailedRecipientException& exception) at System.Net.Mail.SmtpClient.Send(MailMessage message) System.Net.Sockets Verbose: 0 : [0992] Socket#22453229::Dispose() System.Net Verbose: 0 : [0992] Exiting SmtpClient#47606018::Send()
In this example, an exception was actually thrown. The exception basically said I don't have permission to relay through the mail server to send email.
How do I encrypt messages using s/mime or pgp?
You can't. System.Net.Mail does not support encrypted messages.
How do I authenticate to send an email?
To authenticate with System.Net.Mail is much more intuitive than it was with System.Web.Mail. No longer do you have to set a fields property. Instead, you simply create a NetworkCredential's object, and set the username and password.
Below is an example setting the username and password.
- static void Authenticate()
- {
- //create the mail message
- MailMessage mail = new MailMessage();
- //set the addresses
- mail.From = new MailAddress("me@mycompany.com");
- mail.To.Add("you@yourcompany.com");
- //set the content
- mail.Subject = "This is an email";
- mail.Body = "this is the body content of the email.";
- //send the message
- SmtpClient smtp = new SmtpClient("127.0.0.1");
- //to authenticate we set the username and password properites on the SmtpClient
- smtp.Credentials = new NetworkCredential("username", "secret");
- smtp.Send(mail);
- }
How do I change the SMTP port number?
Changing the SMTP port (the port email will be sent to), is also much easier than it was in System.Web.Mail. In System.Net.Mail, you simply set the .Port property on the SmtpClient object.
Below is an example that changes the SMTP port to the lesser used port number 587.
- static void ChangePort()
- {
- //create the mail message
- MailMessage mail = new MailMessage();
- //set the addresses
- mail.From = new MailAddress("me@mycompany.com");
- mail.To.Add("you@yourcompany.com");
- //set the content
- mail.Subject = "This is an email";
- mail.Body = "this is the body content of the email.";
- //send the message
- SmtpClient smtp = new SmtpClient("127.0.0.1");
- //to change the port (default is 25), we set the port property
- smtp.Port = 587;
- smtp.Send(mail);
- }
How do I embed images in an email?
Embedding images is something that is new with System.Net.Mail. To embed an image you will need to
-
Create a LinkedResource object. The LinkedResource will actually contain the binary data of the Image. This binary data is encoded as part of the email, and sent along as part of the MailMessage.
-
Give the LinkedResource a unique name, also known as a Content-Id.
-
Create a HTML AlternateView.
-
Inside that HTML text, you need to use the standard <img> tag.
-
For the "src" value, you need to point it at the Content-Id of the LinkedResource image. This is done by using the syntax <img src="cid:whatever"> The "src=cid:" part is required for the email client to recognize the <img> tag as an embedded image, while the "whatever" part is the actual Content-Id of the LinkedResource image. This will instruct the mail client to find an embedded image named "whatever" and display the contents *without* making a http:// request.
That's all there is to create a linked image. Below is a short but complete example that demonstrates creating an embedded image.
- static void EmbedImages()
- {
- //create the mail message
- MailMessage mail = new MailMessage();
- //set the addresses
- mail.From = new MailAddress("me@mycompany.com");
- mail.To.Add("you@yourcompany.com");
- //set the content
- mail.Subject = "This is an email";
- //first we create the Plain Text part
- AlternateView plainView = AlternateView.CreateAlternateViewFromString("This is my plain text content, viewable by those clients that don't support html", null, "text/plain");
- //then we create the Html part
- //to embed images, we need to use the prefix 'cid' in the img src value
- //the cid value will map to the Content-Id of a Linked resource.
- //thus <img src='cid:companylogo'> will map to a LinkedResource with a ContentId of 'companylogo'
- AlternateView htmlView = AlternateView.CreateAlternateViewFromString("Here is an embedded image.<img src=cid:companylogo>", null, "text/html");
- //create the LinkedResource (embedded image)
- LinkedResource logo = new LinkedResource( "c://temp//logo.gif" );
- logo.ContentId = "companylogo";
- //add the LinkedResource to the appropriate view
- htmlView.LinkedResources.Add(logo);
- //add the views
- mail.AlternateViews.Add(plainView);
- mail.AlternateViews.Add(htmlView);
- //send the message
- SmtpClient smtp = new SmtpClient("127.0.0.1"); //specify the mail server address
- smtp.Send(mail);
- }
How do I send an email over SSL?
Sending an email over Ssl is really simply with System.Net.Mail. In fact, all you need to do is set the .EnableSsl property on the SmtpClient property to true.
Below you will find an example of of SMTP over SSL.
Note: Due to what I believe is a bug in System.Net.Mail you *cannot* use SSL and Credentials (username/password) at the same time. I was never able to get that to work. I always got an exception from the remote mail server. I believe it has to do with the steps System.Net.Mail takes to initiate the SSL session and SMTP authentication.
- static void SSL()
- {
- //create the mail message
- MailMessage mail = new MailMessage();
- //set the addresses
- mail.From = new MailAddress("me@mycompany.com");
- mail.To.Add("you@yourcompany.com");
- //set the content
- mail.Subject = "This is an email";
- mail.Body = "this is the body content of the email.";
- //Port 587 is another SMTP port
- SmtpClient smtp = new SmtpClient("127.0.01", 587);
- smtp.EnableSsl = true;
- smtp.Send(mail);
- }
How do I send email asynchronously?
System.Net.Mail has also added asynchronous support for sending email. To send asynchronously, you need need to
- Wire up a SendCompleted event
- Create the SendCompleted event
- Call SmtpClient.SendAsync
These steps are demonstrated in the code below.
- static void SendAsync()
- {
- //create the mail message
- MailMessage mail = new MailMessage();
- //set the addresses
- mail.From = new MailAddress("me@mycompany.com");
- mail.To.Add("you@yourcompany.com");
- //set the content
- mail.Subject = "This is an email";
- mail.Body = "this is the body content of the email.";
- //send the message
- SmtpClient smtp = new SmtpClient("127.0.0.1"); //specify the mail server address
- //the userstate can be any object. The object can be accessed in the callback method
- //in this example, we will just use the MailMessage object.
- object userState = mail;
- //wire up the event for when the Async send is completed
- smtp.SendCompleted += new SendCompletedEventHandler(SmtpClient_OnCompleted);
- smtp.SendAsync( mail, userState );
- }
- public static void SmtpClient_OnCompleted(object sender, AsyncCompletedEventArgs e)
- {
- //Get the Original MailMessage object
- MailMessage mail= (MailMessage)e.UserState;
- //write out the subject
- string subject = mail.Subject;
- if (e.Cancelled)
- {
- Console.WriteLine("Send canceled for mail with subject [{0}].", subject);
- }
- if (e.Error != null)
- {
- Console.WriteLine("Error {1} occurred when sending mail [{0}] ", subject, e.Error.ToString());
- }
- else
- {
- Console.WriteLine("Message [{0}] sent.", subject );
- }
- }
How do I write to the Pickup directory?
Writing email to the IIS Server's SMTP service pickup directory is another new feature of System.Net.Mail. The SMTP pickup directory is a special directory used by Microsoft's SMTP service to send email. Any email files found in that directory are processed and delivered over SMTP. If the delivery process fails, the files are stored in a queue directory for delivery at another time. If a fatal error occurs (such as a DNS resolution error), the files are moved to the Badmail directory.
By writing to the pickup directory, this speeds up the process because the entire chatting SMTP layer used for relaying is by passed. Below is an example of how to write directly to the Pickup directory.
- public static void PickupDirectory()
- {
- //create the mail message
- MailMessage mail = new MailMessage();
- //set the addresses
- mail.From = new MailAddress("me@mycompany.com");
- mail.To.Add("you@yourcompany.com");
- //set the content
- mail.Subject = "This is an email";
- mail.Body = "this is the body content of the email.";
- //if we are using the IIS SMTP Service, we can write the message
- //directly to the PickupDirectory, and bypass the Network layer
- SmtpClient smtp = new SmtpClient();
- smtp.DeliveryMethod = SmtpDeliveryMethod.PickupDirectoryFromIis;
- smtp.Send(mail);
- }
How do I send a web page?
System.Net.Mail does not natively support sending a web page. However, using the WebRequest class, you can screen scrape web pages, and pass the resulting Html string to the MailMessage object. The following example demonstrates this technique.
Note: Be sure to import the System.Net and System.IO namespaces for this code snippet.
- public static void EmailWebPage()
- {
- //create the mail message
- MailMessage mail = new MailMessage();
- //set the addresses
- mail.From = new MailAddress("me@mycompany.com");
- mail.To.Add("you@yourcompany.com");
- //set the content
- mail.Subject = "This is an email";
- //screen scrape the html
- string html = ScreenScrapeHtml("http://localhost/example.htm");
- mail.Body = html;
- mail.IsBodyHtml = true;
- //send the message
- SmtpClient smtp = new SmtpClient("127.0.0.1");
- smtp.Send(mail);
- }
- public static string ScreenScrapeHtml(string url)
- {
- WebRequest objRequest = System.Net.HttpWebRequest.Create(url);
- StreamReader sr = new StreamReader(objRequest.GetResponse().GetResponseStream());
- string result = sr.ReadToEnd();
- sr.Close();
- return result;
- }
How do I send non US-ASCII emails?
In the beginning, when email was first being used, it was all us-ascii content. To handle different languages and character sets, different encodings must be used. The following example demonstrates sending a non us-ascii email, using the ISO-8859-1 character set as an example. The hardest part of sending non us-ascii email, is to determine the correct character set. For reference, an easy to use character set chart can be found at aspNetEmail's website, here: http://www.aspnetemail.com/charsets.aspx .
The following example demonstrates this technique.
- public static void NonAsciiMail()
- {
- //create the mail message
- MailMessage mail = new MailMessage();
- //set the addresses
- mail.From = new MailAddress("me@mycompany.com");
- mail.To.Add("you@yourcompany.com");
- //set the content
- mail.Subject = "This is an email";
- //to send non-ascii content, we need to set the encoding that matches the
- //string characterset.
- //In this example we use the ISO-8859-1 characterset
- mail.Body = "this text has some ISO-8859-1 characters: âÒÕÇ";
- mail.BodyEncoding = Encoding.GetEncoding("iso-8859-1");
- //send the message
- SmtpClient smtp = new SmtpClient("127.0.0.1");
- smtp.Send(mail);
- }