Implementation of ASP. NET's automatic mail sending Function

Source: Internet
Author: User
Sometimes we need to add the email sending function to the website. For example, an online contribution system sends an email to the author when the manuscript is used. The following uses this function as an example to describe how to automatically send emails.

First, let's talk about how to send emails in. Net .. Net has prepared classes related to sending emails for us. It is very convenient to call them directly. The following is an email notification class I wrote: /// <summary> /// email notification service class. /// </Summary> public class EmailNotificationService {/// <summary> /// create an instance of the mail Notification Service class. /// </Summary> /// <param name = "smtpService"> SMTP Server IP address </param> /// <param name = "enableSSL"> whether to use SSL connect to the SMTP server </param> /// <param name = "port"> SMTP server port </param> /// <param name = "loginName"> used to log on to SMTP server Username </param> /// <param name = "password"> logon password </param> public EmailNotificationService (string smtpService, bool enableSSL, int port, string loginName, string password) {this. m_smtpService = smtpServic E; this. m_loginName = loginName; this. m_password = password; this. m_enableSSL = enableSSL; this. m_port = port;} private readonly string m_smtpService; private readonly string m_loginName; private readonly string m_password; private readonly bool m_enableSSL; private readonly int m_port; /// <summary> /// send an EMAIL notification to the specified EMAIL address. /// </Summary> /// <param name = "senderName"> name displayed in the "sender" column </param> /// <param name =" address "> Target EMAIL address </param> /// <param name =" title "> EMAIL title </param> /// <param name =" content "> EMAIL content </param> public void SendTo (string senderName, string address, string title, string content) {MailMessage mail = new MailMessage (); mail. to. add (address); mail. from = new MailAddress (this. m_loginName, senderName, Encoding. UTF8); mail. subject = title; mail. body = content; mail. bodyEncoding = Encoding. UTF8; mail. isBodyHtml = false; mail. priority = MailPriority. normal; SmtpClient smtp = new SmtpClient (); smtp. credentials = new NetworkCredential (this. m_loginName, this. m_password); smtp. host = this. m_smtpService; smtp. enableSsl = this. m_enableSSL; smtp. port = this. m_port; smtp. send (mail) ;}} in use, first construct an EmailNotification Service class, and then call the SendTo method. For example: emailicationicationservice mailNotificationService = new EmailNotificationService ("smtp.gmail.com", true, 587, "LoginName@gmail.com", "LoginPassword"); mailNotificationService. sendTo ("SenderName", "TargetAddress@qq.com", "Title", "Content"); a class for sending mail is created above the mail implementation solution, the next question is when to call this class. Network communication is required for sending emails, which consumes a lot of time. In addition, the Send method of SmtpClient blocks the calling thread. Once this method is called, you must wait until the email is sent or an error occurs to end the method call. Therefore, you cannot put the call to EmailNotificationService in ASP.. NET page code. If this is done, the client will have to wait a long time to get a response, and the user experience is poor. SmtpClient also has a SendAsync method. The difference between this method and the Send method is that SendAsync is asynchronous. After this method is called, a new thread is generated to Send emails, then the calling thread returns immediately without waiting for the mail to end. Can we use SendAsync instead of Send and call it in the page code? The answer is no. Although the client can quickly obtain the corresponding information, the email is not sent at all. This is caused by ASP. NET page lifecycle is determined by the characteristics of the client to the server, each request, the page will go through a process from generation to destruction, when the page is destroyed, the thread responsible for sending emails is forced to end before sending emails. Due to the ASP. NET page lifecycle feature, we cannot place the calling code in the page code. We need a page-independent thread, which always exists when the website is running. My solution is to use a global object to manage a mail sending thread and maintain a linked list of emails to be sent. When a global object is created, there is no content in the linked list, and the mail sending thread is suspended. When an email is sent for processing on a page, the information related to the sent email is added to the linked list of the sent email. At this time, the linked list is not empty. The sending mail thread starts to work. The Mail Information in the linked list is retrieved and sent one by one until the linked list is empty, and the linked list is suspended again. This loop is repeated. The basic idea of implementing the mail sending function has been fixed, and the next step is to write code. First, define a class to encapsulate the information about the mail to be sent. This article begins with an online contribution system as an example, so the information used here is related to this application. /// <Summary> /// encapsulate the class of information required for sending an email. /// </Summary> public class mailpolicyinfo {// <summary> /// obtain or set the title of the manuscript. /// </Summary> public string Title {get; set ;}/// <summary> // obtain or set the name of the author of the manuscript. /// </Summary> public string Author {get; set ;}/// <summary> // obtain or set the Author's email address. /// </Summary> public string EmailAddress {get; set ;}/// <summary> // obtain or set the manuscript status. /// </Summary> public ArticleStatus {get; set ;}} is then the definition of the global object class. I use the single-piece mode to implement its global structure. /// <Summary> /// class used to process mail sending. /// </Summary> public class NotificationHandler {/// <summary> /// static instance of this class. /// </Summary> private static readonly NotificationHandler g_instance = new NotificationHandler (); /// <summary> /// obtain the unique instance of this class. /// </Summary> public static NotificationHandler Instance {get {return g_instance ;}/// <summary> // default constructor. /// </Summary> private NotificationHandler () {this. m_lockObject = new object (); this. m_mailpolicyinfos = new shortlist <mailpolicyinfo> (); this. m_threadEvent = new ManualResetEvent (false); this. m_workThread = new Thread (this. threadStart); this. m_workThread.Start ();} private readonly worker list <mailpolicyinfo> m_mailpolicyinfos; private readonly Thread m_workThread; private readonly ManualResetEv Ent m_threadEvent; private readonly Object m_lockObject; // <summary> /// add information about the email to be sent. /// </Summary> public void AppendNotification (mailpolicyinfo) {lock (this. m_lockObject) {this. m_mailpolicyinfos.addlast (mailpolicyinfo); if (this. m_mailpolicyinfos.count! = 0) {this. m_threadEvent.Set () ;}}/// <summary> // execution method of the mail sending thread. /// </Summary> private void ThreadStart () {while (true) {this. m_threadEvent.WaitOne (); mailpolicyinfo = this. m_mailNotifyInfos.First.Value; EmailNotificationService mailNotificationService = new EmailNotificationService ("smtp.gmail.com", true, 587, "LoginName@gmail.com", "LoginPassword"); mailnotificationicationservice. sendTo ("Manuscript center", mailpolicyinfo. emailAddress, "Manuscript status change notification", String. format ("{0} Your article {1} has changed to {2}", mailpolicyinfo. author, mailpolicyinfo. title, mailpolicyinfo. articleStatus); lock (this. m_lockObject) {this. m_mailpolicyinfos.remove (mailpolicyinfo); if (this. m_mailpolicyinfos.count = 0) {this. m_threadEvent.Reset () ;}}} this class is relatively simple. First, initialize the member variable in the constructor, and then start the mail sending thread. At this time, this thread is suspended. When the AppendNotification method is called externally, A mailpolicyinfo object is added to the linked list, and then the mail sending thread is awakened. Because the AppendNotification method may be called at the same time in the production environment, synchronization is required here. After the sending thread wakes up, it enters an endless loop and waits for the event object to be triggered. After the event object is set off, emails are sent. After the email is sent, delete the sent email from the linked list and check whether the linked list is empty. If yes, reset the event object and re-enter the pending status. Similarly, the linked list must be synchronized. So far, the mail sending function has been completed. You only need to call mailpolicyinfo = new mailpolicyinfo ();..... notificationHandler. instance. appendNotification (mailNotifyInfo); this is just a very crude Framework and is not complete yet. For example, assume that the website runs continuously and does not consider sending mail threads when the website is closed. On this basis, you can improve it. In addition, automatic mail is also a common function, such as regular check for a condition. If yes, the mail will be sent. To enable automatic email sending, you only need to slightly modify the solution in this article: Add a Timer to icationicationhandler and regularly execute a method. In this method, perform a condition check and trigger an event.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.