AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=1354&pId=-1
Sending HTML Mail with Embedded Image in .NET
page
by Soyuj Kumar Sahoo
Feedback
Average Rating: 
Views (Total / Last 10 Days): 387942/ 99

Introduction

After writing a couple of articles on CLR integration (in SQL Server 2005) technology this one is my first article purely based on .NET. I guess we all are habituated with emails. Sometimes we need to transfer more information in emails so we attach files, presentations, images, etc. and when we need it to be more attractive and colorful then we try our hand with HTML and insert images as necessary to make it more meaningful.

When we need to build this type of actions in our application, then we search for related   Components and Libraries to get support from. So, let us discuss .NET supported libraries to achieve this type of action in our application. In this article we will cover the System.Net.Mail Namespace of System.dll in .NET Framework 2.0 to build a mailing application.

About System.Net.Mail

This is the Namespace that contains the Classes used to send E-Mail using a SMTP (Simple Mail Transfer Protocol) client in .NET. There are four main Classes of our interest, namely MailMessage: represents the content of a mail, SmtpClient: responsible for delivering the Mails using a SMTP Server, Attachment: used in attaching files with mail content, and AlternateView: represents the MIME format to view a mail as an alternative.

This Namespace also contains some enumerations (enum) to specify different mail headers. Among them, "MailPriority" specifies the priority of a MailMessage, which is used later in our examples.

Objective

We are going to build a Service or Application that will Send Mail with some interesting features, like body content in html format, send to multiple recipients, send mail with attachment(s), to make it more meaningful send Html mail with Images Embedded in it, send HTML mail with embedded images and attachments, and mail with multipart bodies.

Steps in making a mail sending application

1.       A simple HTML mail

2.       A High priority mail with multipart bodies

3.       A mail with multiple recipients and attachments

4.       An HTML mail with embedded image

A simple HTML mail

Let us check a mail message created by System.Net.Mail.MailMessage to send a default mail.

Listing 1 – Sample for plain mail

Public Sub SendPlainMail()
 
  'create the mail message
  Dim mail As New MailMessage("from@fromdomain.com""to@todomain.com")
 
  'set the message content
  mail.Subject = "This is a plain text mail"
  mail.Body = "This is a sample body... for default Mail Clients.."
 
  'send the mail using SMTP Client
  Dim smtp As New SmtpClient("My Mail Server"'mail Server IP or NAME 
  smtp.Send(mail)
End Sub ' End SendPlainMail

Here, "mail" is the instance of MailMessage Class. There are four overloaded constructors available initializing different properties of MailMessage Class during making instance.

·         MailMessage (): Initializes an empty instance of the MailMessage class. 

·         MailMessage (from as MailAddress, to as MailAddress): Initializes a new instance of the   MailMessage class by using from and to as MailAddress class objects. 

·         MailMessage (from as String, to as String): Initializes a new instance of the MailMessage class by using from and to as String objects. 

·         MailMessage (from as String, to as String, subject as String, body as String): Initializes a new instance of the MailMessage class by using from, to, subject and body as String objects. 

Again, "smtp" is the instance of SmtpClient Class with Mail Server as parameter, which does the actual mail sending action. There are three available constructors of SmtpClient Class as:

·         SmtpClient (): Initializes a new instance of the SmtpClient class.

·         SmtpClient (host as String): Initializes a new instance of the SmtpClient class that sends email by using the specified SMTP server (host). 

·         SmtpClient (host as String, port as Int32): Initializes a new instance of the SmtpClient class that sends email by using the specified SMTP server and port. 

The MIME Source for above mail is:

Listing 2

'--------------------------------
x-recipient: <to@todomain.com>
Received: xxxxxxxxxxxx xxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxx
(###### #, #, #, #); Fri, 22 Jun 07 18:53:37 +0530
mime-version: 1.0
from: from@fromdomain.com
to: to@todomain.com
date: 22 Jun 2007 18:53:37 +0530
subject: This is a plain text mail
content-type: text/plain; charset=us-ascii
content-transfer-encoding: quoted-printable
Message-Id: <f0706221908020DDAxxxxxx>
X-Antivirus: AVG for E-mail 7.5.472 [269.9.4/860]
This is a sample body... for default Mail Clients..
'--------------------------------

Here, the "content-type" field value is "text/plain," i.e. content-type: text/plain, which specifies that this Mail Client (Outlook or Eudora) is a plain mail only.

By default the mail message created by System.Net.Mail is a plain text, whose default value for   the Public Property MailMessage.IsBodyHtml is False. To format a message as Html we need to set this property MailMessage.IsBodyHtml property to True.

Listing 3 – Sample for HTML mail

Public Sub SendHtmlMail()
 
  'create the mail message
  Dim mail As New MailMessage("from@fromdomain.com""to@todomain.com")
 
   'set the message content
   mail.Subject = "This mail has Html Body.."
   mail.Body = "This is a sample body with html in it. <b>This is bold</b> <font
   color=#336699>This is blue</font>"
   mail.IsBodyHtml = True
   'send mail
   SendMail(mail)
End Sub ' End SendHtmlMail
 
Private Sub SendMail(ByVal mail As Mail.MailMessage)
  'send the message using SMTP client
  Dim smtp As New SmtpClient(_mailServer) 'mail Server IP or NAME
  smtp.Credentials = CredentialCache.DefaultNetworkCredentials
  smtp.Send(Mail)
End Sub ' End SendMail

The MIME Source for above mail is:

Listing 4 – Mime source of HTML mail

'--------------------------------
x-recipient: <to@todomain.com>
Received: xxxxxxxxxxxx xxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxx
(###### #, #, #, #); Fri, 22 Jun 07 18:59:12 +0530
mime-version: 1.0
from: from@fromdomain.com
to: to@todomain.com
date: 22 Jun 2007 18:59:12 +0530
subject: This mail has Html Body..
content-type: text/html; charset=us-ascii
content-transfer-encoding: quoted-printable
Message-Id: <f0707041437531C0Axxxxxx>
X-Antivirus: AVG for E-mail 7.5.475 [269.9.4/860]
This is a sample body with html in it. <b>This is bold</b> 
<font color=3D#336699>This=is blue </font>
'--------------------------------

The "content-type" field value is "text/html" i.e. content-type: text/html, which specifies to the Mail Client (Outlook or Eudora) that this mail contains html content.

A High priority mail with multi part bodies

This example will demonstrate how to create a Multi-Part mime message. Multi-Part messages are messages that contain alternate body parts (at least 2 alternate body parts). Alternate body parts are used for displaying different content to different mail clients (like those who supports HTML). Because it is impossible to sniff or determine an end user's mail client application, i.e. whether it supports for Html or not, we need to create different alternate body parts. Then it is up to the mail client to display the richest body part that they can render. 

Again, the priority of a message is controlled by headers; in the System.Net.Mail namespace, the Priority of a message is actually exposed as a property of the MailMessage Class.

A priority can have the following values from MailPriority enum of System.Net.Mail namespace: High, Low, and Normal.

The following example creates the most common Multi-Part mime email, a Plain Text and an HTML Text email (2 alternate body parts) with High Priority.

Listing 5 – Sample for a multi-part mail

Public Sub MultiPartMailBody()
 
        'create the mail message
        Dim mail As New MailMessage("from@fromdomain.com""to@todomain.com")
 
        'set the message header
        mail.Subject = " This is a Multipart mail with hight Priority"
        mail.Priority = MailPriority.High
 
        'first we create the Plain Text part
        Dim plainView As AlternateView =
        AlternateView.CreateAlternateViewFromString("This is my plain 
        text content, viewable by those clients that don't support html"Nothing,
        "text/plain")
        mail.AlternateViews.Add(plainView)
 
        'then we create the Html part
        Dim htmlView As AlternateView =
        AlternateView.CreateAlternateViewFromString("<b>This is bold text, and
        viewable by those mail clients that support html</b>"Nothing,
        "text/html")
        mail.AlternateViews.Add(htmlView)
        'send mail
        SendMail(mail)
 
End Sub ' End MultiPartMailBody

"PlainView" and "htmlView" are the instances of AlternateView Class, which represents the format to view an email message. CreateAlternateViewFromString creates multi part mime body from the content specified in string.

The MIME Source for above mail is:

Listing 6

'--------------------------------
x-recipient: <to@todomain.com>
Received: xxxxxxxxxxxx xxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxx
(###### #, #, #, #); Fri, 22 Jun 07 19:29:47 +0530
mime-version: 1.0
from: from@fromdomain.com
to: to@todomain.com
x-priority: 1
priority: urgent
importance: high
date: 22 Jun 2007 19:29:47 +0530
subject: This is a Multipart mail with high Priority
content-type: multipart/mixed; 
boundary=--boundary_0_d9be2464-dee8-4289-b8d3-f511389ec089
Message-Id: <f070704107052947xxxxxx>
X-Antivirus: AVG for E-mail 7.5.475 [269.9.4/860]
----boundary_0_d9be2464-dee8-4289-b8d3-f511389ec089
content-type: multipart/alternative; 
boundary=--boundary_1_f3c1985c-738d-4224-9e2f-8fd6d1e10548
----boundary_1_f3c1985c-738d-4224-9e2f-8fd6d1e10548
content-type: text/plain; charset=us-ascii
content-transfer-encoding: quoted-printable
This is my plain text content, 
viewable by those clients that don't support= html
----boundary_1_f3c1985c-738d-4224-9e2f-8fd6d1e10548
content-type: text/html; charset=us-ascii
content-transfer-encoding: quoted-printable
 
<b>This is bold text, and viewable by those mail clients that support html</b>
----boundary_1_f3c1985c-738d-4224-9e2f-8fd6d1e10548--
----boundary_0_d9be2464-dee8-4289-b8d3-f511389ec089--
'--------------------------------                     

The "boundary" of "content-type:" is the separator between two views of mail message.

A mail with multiple recipients and attachments

The "From" property of MailMessage is of MailAddress type. But the To, CC, and Bcc properties of MailMessage are MailAddress collections. So to add additional recipients, all we need to do is call .Add(...) on the respective properties.

Below is an example that demonstrates adding multiple To, CC, and Bcc addresses.

Listing 7 – Sample for attachment mail

Public Sub MultipleRecipients()
 
        'create the mail message
        Dim mail As New MailMessage()
 
        'set the addresses
        '-----------------------------------
        'to specify a friendly 'from' name, we use a different display name
        mail.From = New MailAddress("from@fromdomain.com""Display Name")
 
        'since the To, Cc, and Bcc properties are collections, to add multiple
         addreses, we simply call .Add(...) multple times
        mail.To.Add("to@todomain.com")
        mail.To.Add("to2@to2domain.com")
        mail.CC.Add("cc1@cc1domain.com")
        mail.CC.Add("cc2@cc2domain.com")
        mail.Bcc.Add("bcc1@bcc1domain.com")
        mail.Bcc.Add("bcc2@bcc2domain.com")
        '-----------------------------------
 
        'set the mail content
        mail.Subject = "This is an email with attachment"
        mail.Body = "This is the body content of the email."
 
        'set the attachment
        mail.Attachments.Clear()
        Dim attachment1 As New Attachment("c:\attachment\image1.jpg")
        mail.Attachments.Add(attachment1)
        mail.Attachments.Add(New Attachment("c:\attachment\text1.txt"))
 
        'send mail
        SendMail(mail)
 
End Sub ' End MultipleRecipients

Here, "attachment1" is the instance of Attachment Class of System.Net.Mail namespace, which is a property of MailMessage to get the attachment collection used to store data attached.

One part of MIME Source for above mail is:

Listing 8 – Mime source of a mail with attachment

'--------------------------------
subject: This is an email with attachment
content-type: multipart/mixed; 
boundary=--boundary_0_967ab941-2985-4b6a-8a69-adfb17fb1951
Message-Id: <f0707041632541xxxxxxxxx>
X-Antivirus: AVG for E-mail 7.5.476 [269.9.14/885]
----boundary_0_967ab941-2985-4b6a-8a69-adfb17fb1951
content-type: text/plain; charset=us-ascii
content-transfer-encoding: quoted-printable
This is the body content of the email.
----boundary_0_967ab941-2985-4b6a-8a69-adfb17fb1951
content-type: application/octet-stream; name=image1.jpg
content-transfer-encoding: base64
/9j/4AAQSkZJRgABAQEAYABgAAD/4QAWRXhpZgAASUkqAAgAAAAAAAAAAAD/2wBDAAEBAQEB
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
EBAQEBAQE... .....  ......  ....   ..  ..  .
..... ....   .........  ...  ...  .. .. ..
----boundary_0_967ab941-2985-4b6a-8a69-adfb17fb1951
content-type: application/octet-stream; name=text1.txt
content-transfer-encoding: base64
SGkgVGhpcyBmaWxlIGlzIGF0dGFjaGVkIGZpbGUuDQoNCkNhbiB1IHJlYWQgdGhpcyBmaWxl
Lg0KD.................
----boundary_0_967ab941-2985-4b6a-8a69-adfb17fb1951--
'--------------------------------
An Html mail with embedded image

Embedding images is something that is new with System.Net.Mail in .NET Framework 2.0. To embed an image we will need to:

·         Create an AlternateView object for the Image. The AlternateView 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.

·         Set the ContentId property of AlternateView Class to a unique value.

·         Create a HTML AlternateView.

·         Inside that HTML text, we need to use the standard <img> tag.

·         For the "src" value, we need to point it at the Content-Id of the AlternateView image. This is done by using the syntax <img src="cid:ContentId value">. The "src=cid:" part is required for the email client to recognize the <img> tag as an embedded image, while the "ContentId value" part is the actual Content-Id of the AlternateView image. 

That is all there is to create an embedded image view. Below is a short but complete example that demonstrates creating an embedded image message.

Listing 9 – Sample of an Html mail with embedded image

Public Sub EmbeddedImages()
 
        'create the mail message
        Dim mail As New MailMessage()
 
        'set the addresses
        mail.From = New MailAddress("from@fromdomain.com", " Display Name")
        mail.To.Add("to@todomain.com")
       
        'set the content
        mail.Subject = "This is an embedded image mail"
 
        'first we create the Plain Text part
        Dim palinBody As String = "This is my plain text content, viewable by
        those clients that don't support html"
        Dim plainView As AlternateView =
        AlternateView.CreateAlternateViewFromString(palinBody, Nothing,
        "text/plain")
        'then we create the Html part
        'to embed images, we need to use the prefix 'cid' in the img src value
        Dim htmlBody As String = "<b>This is the embedded image 
        file.</b><DIV>&nbsp;</DIV>"
        htmlBody += "<img alt="""" hspace=0 src=""cid:uniqueId"" align=baseline 
        border=0 >"
        htmlBody += "<DIV>&nbsp;</DIV><b>This is the end of Mail...</b>"
        Dim htmlView As AlternateView =
         AlternateView.CreateAlternateViewFromString(htmlBody, Nothing,
         "text/html")
 
        'create the AlternateView for embedded image
        Dim imageView As New AlternateView("c:\attachment\image1.jpg",
        MediaTypeNames.Image.Jpeg)
        imageView.ContentId = "uniqueId"
        imageView.TransferEncoding = TransferEncoding.Base64
 
        'add the views
        mail.AlternateViews.Add(plainView)
        mail.AlternateViews.Add(htmlView)
        mail.AlternateViews.Add(imageView)
 
        'send mail
        SendMail(mail)
 
End Sub ' End EmbedImages

"ImageView" is the instance of AlternateView created using the constructor which takes two parameters as: fileName (with path of image) as String, and mediaType as String. Here we use the public string type constant "Jpeg" of MediaTypeNames.Image Class, which is actually “image/jpeg."

Again, the "TransferEncoding" property of "imageView" (AlternateView Class) is set to "Base64."

Sample source code

Let us check the steps for creating a sample Mail Sending application in Visual Basic 2005. We have to follow the steps below.

·         Open Visual Studio 2005 and create a new console application project. Named it "MailSendingApp."

·         Copy and paste the following codes in that module and named it "SampleModule.vb."

Listing 10 – Sample source code of Mail sending application

Imports System.Net
Imports System.Net.Mail
Imports System.Net.Mime
Module SampleModule
 
    Private _mailServer As String = String.Empty
 
    ''' <summary>
    ''' The starting function of console application.
    ''' </summary>
    ''' <remarks>Need to set the mail server details from console</remarks>
    Sub Main()
 
        Console.WriteLine("Welcome to Soyuj's Mail send application..")
        Console.WriteLine("Enter your Mail Server :: ")
        _mailServer = Console.ReadLine()
 
        EmbeddedImages()
 
        Console.WriteLine(ControlChars.CrLf & "Completed...")
        Console.ReadLine()
 
    End Sub
 
    ''' <summary>
    ''' Sends mail using SMTP client
    ''' </summary>
    ''' <param name="mail">The SMTP server (MailServer) as String</param>
    ''' <remarks>It can use the IP of Server also</remarks>
    Private Sub SendMail(ByVal mail As Mail.MailMessage)
 
        'send the message using SMTP client
        Dim smtp As New SmtpClient(_mailServer) 'mail Server IP or NAME 
        smtp.Credentials = CredentialCache.DefaultNetworkCredentials
        smtp.Send(Mail)
 
    End Sub ' End SendMail
 
    ''' <summary>
    ''' Sets the content of MailMessage for default(plain text)
    ''' </summary>
    ''' <remarks>This is accessible by all Mail Clients</remarks>
    Public Sub SendPlainMail()
 
        'create the mail message
        Dim mail As New MailMessage("from@fromdomain.com""to@todomain.com")
 
        'set the message content
        mail.Subject = "This is a plain text mail"
        mail.Body = "This is a sample body... for default Mail Clients.."
 
        'send the mail using SMTP Client
        Dim smtp As New SmtpClient("My Mail Server") 'mail Server IP or NAME 
        smtp.Send(mail)
 
    End Sub ' End SendPlainMail
 
    ''' <summary>
    ''' Sets the content of MailMessage for a Html body only
    ''' </summary>
    ''' <remarks>The Html body is created using standard html tags..</remarks>
    Public Sub SendHtmlMail()
 
        'create the mail message
        Dim mail As New MailMessage("from@fromdomain.com""to@todomain.com")
 
        'set the message content
        mail.Subject = "This mail has Html Body.."
        mail.Body = "body with html<b>bold</b> <font color=#336699>blue</font>"
        mail.IsBodyHtml = True
 
        'send mail
        SendMail(mail)
 
    End Sub ' End SendHtmlMail
 
    ''' <summary>
    ''' Sets the MailMessage content with multiple body parts
    ''' (e.g a Html part and a PlainText part..)
    ''' </summary>
    ''' <remarks>Plain body is for Mail Clients, 
    ''' those don't support Html</remarks>
    Public Sub MultiPartMailBody()
 
        'create the mail message
        Dim mail As New MailMessage("from@fromdomain.com", "to@todomain.com")
 
        'set the message header
        mail.Subject = " This is a Multipart mail with hight Priority"
        mail.Priority = MailPriority.High
 
        'first we create the Plain Text part
        Dim plainView As AlternateView =
            AlternateView.CreateAlternateViewFromString(
            "Plain text content, viewable by clients that don't support html",
            Nothing"text/plain")
        mail.AlternateViews.Add(plainView)
 
        'then we create the Html part
        Dim htmlView As AlternateView = 
            AlternateView.CreateAlternateViewFromString(
            "<b>bold text, viewable by mail clients that support html</b>",
            Nothing"text/html")
        mail.AlternateViews.Add(htmlView)
 
        'send mail
        SendMail(mail)
 
    End Sub ' End MultiPartMailBody
 
    ''' <summary>
    ''' Set the MailMessage instance for multiple recipients with attachment
    ''' </summary>
    ''' <remarks>From address can be customized to show a Display Name</remarks>
    Public Sub MultipleRecipients()
 
        'create the mail message
        Dim mail As New MailMessage()
 
        'set the addresses
        '-----------------------------------
        'to specify a friendly 'from' name, we use a different display name
        mail.From = New MailAddress("from@fromdomain.com""Display Name")
 
        'since the To, Cc, and Bcc properties are collections, to add multiple
        'addreses, we simply call .Add(...) multple times
        mail.To.Add("to@todomain.com")
        mail.To.Add("to2@to2domain.com")
        mail.CC.Add("cc1@cc1domain.com")
        mail.CC.Add("cc2@cc2domain.com")
        mail.Bcc.Add("bcc1@bcc1domain.com")
        mail.Bcc.Add("bcc2@bcc2domain.com")
        '-----------------------------------
 
        'set the mail content
        mail.Subject = "This is an email with attachment"
        mail.Body = "This is the body content of the email."
 
        'set the attachment
        mail.Attachments.Clear()
        Dim attachment1 As New Attachment("c:\attachment\image1.jpg")
        mail.Attachments.Add(attachment1)
        mail.Attachments.Add(New Attachment("c:\attachment\text1.txt"))
 
        'send mail
        SendMail(mail)
 
    End Sub ' End MultipleRecipients
 
    ''' <summary>
    ''' Embeds an image in a Html body of MailMessage
    ''' </summary>
    ''' <remarks>The standard image tag must be there in html body with 'cid' 
    ''' in src value</remarks>
    Public Sub EmbeddedImages()
 
        'create the mail message
        Dim mail As New MailMessage()
 
        'set the addresses
        mail.From = New MailAddress("from@fromdomain.com"" Display Name")
        mail.To.Add("to@todomain.com")
       
        'set the content
        mail.Subject = "This is an embedded image mail"
 
        'first we create the Plain Text part
        Dim palinBody As String = 
          "Plain text content, viewable by those clients that don't support html"
        Dim plainView As AlternateView =
            AlternateView.CreateAlternateViewFromString
            (palinBody, Nothing, "text/plain")
        'then we create the Html part
        'to embed images, we need to use the prefix 'cid' in the img src value
        Dim htmlBody As String = "<b>Embedded image file.</b><DIV>&nbsp;</DIV>"
        htmlBody += 
        "<img alt="""" hspace=0 src=""cid:uniqueId"" align=baseline border=0 >"
        htmlBody += "<DIV>&nbsp;</DIV><b>This is the end of Mail...</b>"
        Dim htmlView As AlternateView =
             AlternateView.CreateAlternateViewFromString
            (htmlBody, Nothing, "text/html")
 
 
        'create the AlternateView for embedded image
        Dim imageView As New AlternateView("c:\attachment\image1.jpg",
            MediaTypeNames.Image.Jpeg)
        imageView.ContentId = "uniqueId"
        imageView.TransferEncoding = TransferEncoding.Base64
 
 
        'add the views
        mail.AlternateViews.Add(plainView)
        mail.AlternateViews.Add(htmlView)
        mail.AlternateViews.Add(imageView)
 
        'send mail
        SendMail(mail)
 
    End Sub ' End EmbedImages
 
End Module ' End SampleModule
 

·         Change the To, From, Cc, Bcc, etc. address to your type (but must be valid).

·          Press F5 to start debugging and follow the instructions from the console.

Figure 1- (sample console)

·         Enter your Mail Server address.

·         Check the output mail in your Mail Box. My sample output is:

Figure 2 - (Output sample mail)

NOTE: Before using the above code, be sure to set your email addresses in the required place with Mail Server (SMTP).

Conclusion

I believe you are smart enough to change these sample codes for your different uses, such as for Windows Application, Web Application, a Class Library, etc. I have not implemented any exception handling concept for better debugging, this is a task for you. I hope you had a good session with this article.

By Soyuj Kumar Sahoo

MindFire solutions


Product Spotlight
Product Spotlight 

©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-25 4:00:00 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search