Sunday, 16 October 2011

Sending mails with Embedded image using System.Net.Mail

Normally when we send mails, we may face situation sending mails with images. But sending mail by pointing the image using url will not reach the mail with images. This post talks about how to send mails by embedding images.

Sending normal mails:

Dot.Net runtime provides System.Net.Mail namespace for sending mails. Below is a sample code for sending mails without images.
// BasicSendMail.aspx
// using System.Net.Mail;
// using System.Net;
SmtpClient smtp = new SmtpClient("smtp.gmail.com");
MailMessage mssg = new MailMessage();
mssg.From = new MailAddress("myaddress@gmail.com");
mssg.Subject = "Simple Test Mail with Embeded Image";
mssg.Body="This is test mail";

#region SSL Communication  (Nor for all type of SMTP)
smtp.EnableSsl = true; // For sending using SSL SMTP server
NetworkCredential myCreds = new NetworkCredential("myaddress@gmail.com", "sdfsdf", "");
smtp.Credentials = myCreds;
#endregion

mssg.To.Add("toaddress@gmail.com");
mssg.BodyEncoding = System.Text.Encoding.Default;
mssg.SubjectEncoding = System.Text.Encoding.Default;
mssg.IsBodyHtml = true;
smtp.Send(mssg);
Here, the body can be a plain text or HTML script. In case if the body is HTML then, mssg.IsBodyHtml = true otherwise mssg.IsBodyHtml = false.

Basic concept for sending mails with embedded image:

Normally when we send mails with embedding images; the body is in HTML format.

For Example, below is the script used for sending mail:
<div>
    <img width="346" alt="Carina Nebula" title="Carina Nebula" src="Images/Carina_Nebula.jpg" height="260" border="0" />
    <h3>Carina Nebula: 14,000+ Stars</h3>
</div>

The implementation will be
string strBody = "<div><img width=\"346\" alt=\"Carina Nebula\" title=\"Carina Nebula\" src=\"cid:carinanebula\" height=\"260\" border=\"0\" /><h3>Carina Nebula: 14,000+ Stars</h3></div>";
The body contains the HTML script, where the image replaced with an unique id with cid: prefix (Ex: cid:carinanebula). This id will be used further for adding the images embedded using AlternativeView and LinkedResource objects.
AlternateView view = AlternateView.CreateAlternateViewFromString(strBody, null, "text/html");

LinkedResource linked = new LinkedResource(HttpContext.Current.Request.PhysicalApplicationPath + "/Images/Carina_Nebula.jpg");
linked.ContentId = "carinanebula";
view.LinkedResources.Add(linked);
mssg.AlternateViews.Add(view);
As the code shows, first the view must be created using the body. The image will be added using LinkedResource. The unique id will be assigned to ContentId for that image and the LinkedResource will be added to that view.

The complete code for the same example would be.
// Default.aspx
string SmtpServer = ConfigurationManager.AppSettings["App_Mail_Server"]; // Provide the SMTP server name
string strFrom = ConfigurationManager.AppSettings["FromAddress"];
string strTo = ConfigurationManager.AppSettings["ToAddress"];
string strSubject = "Simple Test Mail with Embeded Image";

#region Embadding Image to Mail
string strBody = "<div><img width=\"346\" alt=\"Carina Nebula\" title=\"Carina Nebula\" src=\"cid:carinanebula\" height=\"260\" border=\"0\" /><h3>Carina Nebula: 14,000+ Stars</h3></div>";

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

LinkedResource linked = new LinkedResource(HttpContext.Current.Request.PhysicalApplicationPath + "/Images/Carina_Nebula.jpg");
linked.ContentId = "carinanebula";
view.LinkedResources.Add(linked);
#endregion

try
{
    SmtpClient smtp = new SmtpClient(SmtpServer);
    MailMessage mssg = new MailMessage();
    mssg.From = new MailAddress(strFrom);
    mssg.Subject = strSubject;
    mssg.AlternateViews.Add(view);

    #region SSL Communication
    smtp.EnableSsl = true; // For sending using SSL SMTP server
    NetworkCredential myCreds = new NetworkCredential(ConfigurationManager.AppSettings["SenderAddress"], ConfigurationManager.AppSettings["Password"], "");
    smtp.Credentials = myCreds;
    #endregion

    #region Adding multiple To Addresses
    if (strTo.Trim().Length > 0)
    {
        foreach (string sTo in strTo.Split(",".ToCharArray()))
            mssg.To.Add(sTo);
    }
    #endregion
    mssg.BodyEncoding = System.Text.Encoding.Default;
    mssg.SubjectEncoding = System.Text.Encoding.Default;
    mssg.IsBodyHtml = true;
    smtp.Send(mssg);

}
catch (Exception ex)
{
    //exception
}
The Web.Config contains the required configuration details.
<appSettings>
  <add key="App_Mail_Server" value="smtp.gmail.com" />
  <add key="FromAddress" value="fromaddress@gmail.com" />
  <add key="SenderAddress" value ="senderaddress@gmail.com" />
  <add key="Password" value="P@ssw$$rd" />
  <add key="ToAddress" value="toaddress1@gmail.com, toaddress2@gmail.com" />
</appSettings>

Another Example
Below example shows an example for more understanding on how to implement for an HTML script defined in ASP.NET page.
The ASPX script (SimpleEmbaded.aspx).
<div>
    <asp:Button ID="btnSendMail" runat="server" Text="Send Mail" onclick="btnSendMail_Click" />
</div>
<br />
<div id="divMailContent" runat="server">
<table cellspacing="5" style="width:22em; text-align:left; border-color: #FF3F00;">
    <tbody>
        <tr>
            <th colspan="2" style="text-align:center; font-size:125%; font-weight:bold; background-color:#FFC569; color: black;">
                <span>Kamakshi Amman Temple</span>
            </th>
        </tr>
        <tr>
            <td colspan="2" style="text-align:center;">
                <a href="#" title="The Kamakshi Amman temple has gopurams with gold overlays.">
                    <img alt="" src="Images/280px-Kanchi_Kamakshi_temple22.jpg" width="280" height="250">
                </a>
                <br>
                <span style="padding-top:0.3em; line-height:1.2em">The Kamakshi Amman temple has gopurams with gold overlays.</span>
            </td>
        </tr>
    </tbody>
</table>
</div>
Here, I defined a Div control and designed the content for sending mail on the Web Page. This id will be used to get the content using innerHTML propery of the control. The C# code will be.
string SmtpServer = ConfigurationManager.AppSettings["App_Mail_Server"]; // Provide the SMTP server name
string strFrom = ConfigurationManager.AppSettings["FromAddress"];
string strTo = ConfigurationManager.AppSettings["ToAddress"];
string strSubject = "Simple Test Mail with Embeded Image";

#region Embadding Image to Mail
string strBody = divMailContent.InnerHtml;
strBody = strBody.Replace("Images/280px-Kanchi_Kamakshi_temple22.jpg", "cid:kanchitemple");

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

LinkedResource linked = new LinkedResource(HttpContext.Current.Request.PhysicalApplicationPath + "Images/280px-Kanchi_Kamakshi_temple22.jpg");
linked.ContentId = "kanchitemple";
view.LinkedResources.Add(linked);
#endregion

try
{
    SmtpClient smtp = new SmtpClient(SmtpServer);
    MailMessage mssg = new MailMessage();
    mssg.From = new MailAddress(strFrom);
    mssg.Subject = strSubject;
    mssg.AlternateViews.Add(view);

    #region SSL Communication
    smtp.EnableSsl = true; // For sending using SSL SMTP server
    NetworkCredential myCreds = new NetworkCredential(ConfigurationManager.AppSettings["SenderAddress"], ConfigurationManager.AppSettings["Password"], "");
    smtp.Credentials = myCreds;
    #endregion

    #region Adding multiple To Addresses
    if (strTo.Trim().Length > 0)
    {
        foreach (string sTo in strTo.Split(",".ToCharArray()))
            mssg.To.Add(sTo);
    }
    #endregion
    mssg.BodyEncoding = System.Text.Encoding.Default;
    mssg.SubjectEncoding = System.Text.Encoding.Default;
    mssg.IsBodyHtml = true;
    smtp.Send(mssg);
}
catch (Exception ex)
{
    //exception
}

Note: All the example uses gmail SMTP server as I dont have any SMTP server setup in my network. But the same code can be used for any SMTP server. But, the code between region SSL Communication used to connect SSL SMTP server with authentication mechanism. So this region may required to be removed depends on the SMTP server.

Download the source code
Download the working example in C# here and in VB here.

(Note: Pls change the From Address, To Address and Sender Address before running the example. These example uses gmail as SMTP server, if required pls change. In some network, using gmail (public) SMTP server will not be allowed)

The screenshot of the mail contents will be:




2 Responses to “Sending mails with Embedded image using System.Net.Mail”

  • scorpion_prince says:
    25 May 2012 at 00:27

    Thank you for posting this. It was very informative, and it helped me solve an issue I was facing with setting the size of the LinkedResource image.
    Cheers,
    Prabin

  • Thiru says:
    25 May 2012 at 09:20

    Thanks Prabin :)

Post a Comment