Sunday 18 December 2011

Sending Mail using System.Net.Mail.SmtpClient in ASP.NET (Custom Class)


As part of sending mails using ASP.NET code, this post provides a custom class which can be used for sending normal mails and mails with embedded images.

I have already blogged a post Sending mails with Embedded image using System.Net.Mail previously for sending mails with embedded image.

I have created custom class SendNetMail which gets inputs from, to, cc, bcc, attachments, body and subject information from the code and sends the mail to the specified addresses.

Below is the code for the class SendNetMail:
public class SendNetMail
{
    public string SmtpServer { get; set;}
    public string From { get; set; }
    public string To { get; set; }
    public string CC { get; set; }
    public string BCC { get; set; }
    public string Periority { get; set; }
    public string Attachment { get; set; }
    public string Subject { get; set; }
    public bool IsBodyIsInHTML { get; set; }
    public string Path { get; set; }
    public string Content { get; set; }
    public bool IsSslEnabled { get; set; }
    public SSLNetworkCredential SSLNetworkCredential { get; set; }

    public bool SendMail()
    {
        #region Embadding Image to Mail
        string strTempBody = string.Empty;
        bool IsImageEmbadded = false;

        if (Content == null)
            strTempBody = LoadPage(Path);
        else
            strTempBody = Content;

        string strBody = string.Empty;
        AlternateView view = null;

        if (strTempBody.Contains("src=\"") == true)
        {
            int intImageIndex = 0;
            IsImageEmbadded = true;

            IList<string> imageFiles = new List<string>();
            while (strTempBody.Contains("src=\""))
            {
                strBody += strTempBody.Substring(0, strTempBody.IndexOf("src=") + 5);
                strTempBody = strTempBody.Substring(strTempBody.IndexOf("src=") + 5);
                strBody += "cid:image" + intImageIndex.ToString();

                string strFileName = ResolveUrl(strTempBody.Substring(0, strTempBody.IndexOf("\"")));
                strTempBody = strTempBody.Substring(strTempBody.IndexOf("\"") + 1);

                imageFiles.Add(strFileName);

                strBody += "\"";
                intImageIndex++;
            }

            strBody += strTempBody;

            view = AlternateView.CreateAlternateViewFromString(strBody, null, "text/html");

            --intImageIndex;

            for (int intIndex = intImageIndex; intIndex >= 0; intIndex--)
            {
                LinkedResource linked = new LinkedResource(imageFiles[intIndex]);
                linked.ContentId = "image" + intIndex.ToString();
                view.LinkedResources.Add(linked);
            }
        }
        else
            strBody += strTempBody;
        #endregion

        try
        {
            #region Starts Prepare
            SmtpClient smtp = new SmtpClient(SmtpServer);
            MailMessage mssg = new MailMessage();
            mssg.From = new MailAddress(From);
            mssg.Subject = Subject;

            if (IsImageEmbadded == true)
                mssg.AlternateViews.Add(view);
            else
                mssg.Body = strBody;
            #endregion

            #region SSL Communication
            if (IsSslEnabled == true)
            {
                smtp.EnableSsl = true; // For sending using SSL SMTP server
                NetworkCredential myCreds = new NetworkCredential(SSLNetworkCredential.UserName, SSLNetworkCredential.Password, SSLNetworkCredential.Domain);
                smtp.Credentials = myCreds;
            }
            #endregion

            #region Adding multiple To Addresses
            if (To.Trim().Length > 0)
            {
                foreach (string sTo in To.Split(",".ToCharArray()))
                    mssg.To.Add(sTo);
            }
            #endregion

            #region Adding multiple CC Addresses
            if (CC.Trim().Length > 0)
            {
                foreach (string sCC in CC.Split(",".ToCharArray()))
                    mssg.CC.Add(sCC);
            }
            #endregion

            #region Adding multiple BCC Addresses
            if (BCC.Trim().Length > 0)
            {
                foreach (string sBCC in BCC.Split(",".ToCharArray()))
                    mssg.Bcc.Add(sBCC);
            }
            #endregion

            #region Adding multiple BCC Addresses
            if (Attachment.Trim().Length > 0)
            {
                foreach (string sAttachment in Attachment.Split(",".ToCharArray()))
                {
                    Attachment attachment = new Attachment(sAttachment);
                    mssg.Attachments.Add(attachment);
                }
            }
            #endregion

            #region Mail Periority
            MailPriority mailPeriority = MailPriority.Normal;
            switch (Periority)
            {
                case "High":
                    mailPeriority = MailPriority.High;
                    break;
                case "Low":
                    mailPeriority = MailPriority.Low;
                    break;
                case "Normal":
                    mailPeriority = MailPriority.Normal;
                    break;
            }
            #endregion

            #region Send Mail
            mssg.Priority = mailPeriority;
            mssg.BodyEncoding = System.Text.Encoding.Default;
            mssg.SubjectEncoding = System.Text.Encoding.Default;
            mssg.IsBodyHtml = IsBodyIsInHTML;
            smtp.Send(mssg);
            #endregion
                
            return true;
        }
        catch (Exception ex)
        {
        }
        return false;
    }
    public string LoadPage(string url)
    {
        WebRequest objRequest = System.Net.HttpWebRequest.Create(url);
        StreamReader sr = new StreamReader(objRequest.GetResponse().GetResponseStream());
        string result = sr.ReadToEnd();
        sr.Close();
        return result;
    }
    public string ResolveUrl(string relativeUrl)
    {
        string retVal = string.Empty;
        if (relativeUrl == null) throw new ArgumentNullException("relativeUrl");

        if (relativeUrl.StartsWith("../") == true)
        {
            retVal = HttpContext.Current.Request.PhysicalApplicationPath.Substring(0, HttpContext.Current.Request.PhysicalApplicationPath.LastIndexOf(@"\"));
            while (relativeUrl.StartsWith("../"))
            {
                relativeUrl = relativeUrl.Substring(3);
                retVal = retVal.Substring(0, retVal.LastIndexOf(@"\"));
            }
            retVal = retVal + @"\" + relativeUrl;
        }
        else if (relativeUrl.StartsWith("/") == true)
            retVal = HttpContext.Current.Request.PhysicalApplicationPath + relativeUrl;
        else if (relativeUrl.Length > 0)
            retVal = HttpContext.Current.Request.PhysicalApplicationPath + relativeUrl;

        return retVal;
    }
}

This class required the following inputs from the code.

SmtpServer – The SMTP server address. It can be enterprise SMTP or public provided gmail, yahoo SMTP server.
From – Specifies the From mail address. Ex: fromaddress@dotnettwitter.com
To – Specifies the To mail addresses separated by comma (,) Ex: toaddress1@dotnettwitter.com, toaddress2@dotnettwitter.com
CC – Specifies the CC mail addresses separated by comma (,)
BCC – Specifies the BCC mail address separated by comma (,)
Periority – Specifies the priority of the mail - High, Low, Normal
Attachment – Specifies the attachment files separated by comma (,). Ex: C:\Test\TestExcel.xls, C:\Test\TestTodo.txt
Subject – Specifies the subject of the mail
IsBodyIsInHTML – Specifies whether the body content is an HTML script (true) or plain text (false)
Path – Specifies the html script file name with path if the body content is HTML.
Content – Specifies the HTML content if the body is an HTML script (either Path or Content can be set)
IsSSLConnection – Specifies either the mail required SSL connection (Authentication) for sending mail. Normally the public SMTP provides requires SSL connection enabled such as gmail, yahoo etc.,
SSLNetworkCredential – This input is used to get the user name and password for creating SSL connection.

Below is the code for sending a normal mail to the specified addresses (NormalMail.aspx in the source)
SendNetMail sendNetMail = new SendNetMail();

sendNetMail.SmtpServer = ConfigurationManager.AppSettings["App_Mail_Server"]; // Provide the SMTP server name
sendNetMail.From = ConfigurationManager.AppSettings["FromAddress"];
sendNetMail.To = ConfigurationManager.AppSettings["ToAddress"];
sendNetMail.CC = ConfigurationManager.AppSettings["CcAddress"];  // If no mail id required, give blank
sendNetMail.BCC = ConfigurationManager.AppSettings["BccAddress"]; // If no mail id required, give blank
sendNetMail.Periority = ConfigurationManager.AppSettings["Periority"];
sendNetMail.Attachment = "";
sendNetMail.Subject = "Sending Normal Mail";
sendNetMail.IsBodyIsInHTML = false;
sendNetMail.Content = "This is test mail";
sendNetMail.SSLNetworkCredential = new SSLNetworkCredential(ConfigurationManager.AppSettings["SSLCredentialUserName"], ConfigurationManager.AppSettings["SSLCredentialPassword"]);
sendNetMail.IsSslEnabled = true;

sendNetMail.SendMail();
Here the SMTP server and mail addresses will be defined in Web.Config as defined below.
<appSettings>
  <add key="App_Mail_Server" value="smtp.gmail.com"/>
  <add key="FromAddress" value="fromaddress@gmail.com"/>
  <add key="ToAddress" value="toaddress1@gmail.com, toaddress2@gmail.com"/>
  <add key="CcAddress" value=""/>
  <add key="BccAddress" value=""/>
  <add key="Periority" value="High"/>
  <add key="SSLCredentialUserName" value="fromaddress@gmail.com"/>
  <add key="SSLCredentialPassword" value="p@ssw!!d"/>
</appSettings>
In this example, I use gmail SMTP address for sending mail. So the server require SSL credentials for authentication.

As we seen about the inputs, we can send mail with HTML script also as defined below (HTMLMail.aspx in the source)
SendNetMail sendNetMail = new SendNetMail();

sendNetMail.SmtpServer = ConfigurationManager.AppSettings["App_Mail_Server"]; // Provide the SMTP server name
sendNetMail.From = ConfigurationManager.AppSettings["FromAddress"];
sendNetMail.To = ConfigurationManager.AppSettings["ToAddress"];
sendNetMail.CC = ConfigurationManager.AppSettings["CcAddress"];  // If no mail id required, give blank
sendNetMail.BCC = ConfigurationManager.AppSettings["BccAddress"]; // If no mail id required, give blank
sendNetMail.Periority = ConfigurationManager.AppSettings["Periority"];
sendNetMail.Attachment = "";
sendNetMail.Subject = "Sending HTML Mail";
sendNetMail.IsBodyIsInHTML = true;
sendNetMail.Content = @"<div>Dear Reader,<br/><br/>Below is the information about the website.<br/><br/>" +
                        "<table style='background:gray'>" +
                        "<tr><td>Website Name</td><td>Dot Net Twitter</td></tr> " +
                        "<tr><td>url</td><td>www.dotnettwitter.com</td></tr>" +
                        "<tr><td>Category</td><td>Technology</td></tr>" +
                        "</table></div>";
sendNetMail.SSLNetworkCredential = new SSLNetworkCredential(ConfigurationManager.AppSettings["SSLCredentialUserName"], ConfigurationManager.AppSettings["SSLCredentialPassword"]);
sendNetMail.IsSslEnabled = true;

sendNetMail.SendMail();
This class sends mails with embedded images also. For example, I have an HTML script which has some images referred. When sending mail with HTML script, the mail required to be sent with the images embedded. The HTML script can be assigned to the SendNetMail object in two ways,

1. Pointing where the HTML script file located to the SendNetMail object. So the object will pickup the file and sends the mail. This is very useful when pages created on demand and place it in a folder or publishing at an url.
Below is an html script file stored in the application path for implementing this example (MailContent1.htm).
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
<div id="divMailContent" runat="server">
    <table width="600" border="0" align="center" cellspacing="0" cellpadding="0" style="font-family:Arial, Helvetica, sans-serif">
        <tbody>
        <tr>
            <td style="font-size:11px;color:#171818">
                Dear Friend,
                <br /><br />
                This mail is for testing purpose.
                <br /><br />
            </td>
        </tr>
        </tbody>
    </table>
</div>
</body>
</html>
Below is the code for sending the HTML script file to mail (SendMailPath.aspx in the source code)
SendNetMail sendNetMail = new SendNetMail();

sendNetMail.SmtpServer = ConfigurationManager.AppSettings["App_Mail_Server"]; // Provide the SMTP server name
sendNetMail.From = ConfigurationManager.AppSettings["FromAddress"];
sendNetMail.To = ConfigurationManager.AppSettings["ToAddress"];
sendNetMail.CC = ConfigurationManager.AppSettings["CcAddress"];  // If no mail id required, give blank
sendNetMail.BCC = ConfigurationManager.AppSettings["BccAddress"]; // If no mail id required, give blank
sendNetMail.Periority = ConfigurationManager.AppSettings["Periority"];
sendNetMail.Attachment = "";
sendNetMail.Subject = "Mail with Embeded Image";
sendNetMail.IsBodyIsInHTML = true;
sendNetMail.Path = HttpContext.Current.Request.Url.AbsoluteUri.Substring(0, HttpContext.Current.Request.Url.AbsoluteUri.LastIndexOf("/")) + "/" + "MailContent1.htm";// "MailContent.htm";
sendNetMail.SSLNetworkCredential = new SSLNetworkCredential(ConfigurationManager.AppSettings["SSLCredentialUserName"], ConfigurationManager.AppSettings["SSLCredentialPassword"]);
sendNetMail.IsSslEnabled = true;

sendNetMail.SendMail();
2. Assigning the HTML content directly to the SendNetMail object. This will be useful when a part of the HTML script required to send as mail or the content will be dynamically created at runtime.
The aspx script file includes the HTML script.
<div>
    <asp:Button ID="btnSendMail" runat="server" Text="Send Mail" onclick="btnSendMail_Click" />
</div>
<div id="divMailContent" runat="server">
    <table width="600" border="0" align="center" cellspacing="0" cellpadding="0" style="font-family:Arial, Helvetica, sans-serif">
        <tbody>
        <tr>
            <td style="font-size:11px;color:#171818">
                Dear Friend,
                <br /><br />
                This mail is for testing purpose.
                <br /><br />
            </td>
        </tr>
        </tbody>
    </table>
</div>
The code for sending mail with the div content defined in the script
SendNetMail sendNetMail = new SendNetMail();

sendNetMail.SmtpServer = ConfigurationManager.AppSettings["App_Mail_Server"]; // Provide the SMTP server name
sendNetMail.From = ConfigurationManager.AppSettings["FromAddress"];
sendNetMail.To = ConfigurationManager.AppSettings["ToAddress"];
sendNetMail.CC = ConfigurationManager.AppSettings["CcAddress"];  // If no mail id required, give blank
sendNetMail.BCC = ConfigurationManager.AppSettings["BccAddress"]; // If no mail id required, give blank
sendNetMail.Periority = ConfigurationManager.AppSettings["Periority"];
sendNetMail.Attachment = "";
sendNetMail.Subject = "Mail with Embeded Image";
sendNetMail.IsBodyIsInHTML = true;
sendNetMail.Content = divMailContent.InnerHtml;
sendNetMail.SSLNetworkCredential = new SSLNetworkCredential(ConfigurationManager.AppSettings["SSLCredentialUserName"], ConfigurationManager.AppSettings["SSLCredentialPassword"]);
sendNetMail.IsSslEnabled = true;

sendNetMail.SendMail();

download the working source code in C# here and in VB here.

The sample mail output with embedded images



0 Responses to “Sending Mail using System.Net.Mail.SmtpClient in ASP.NET (Custom Class)”

Post a Comment