Skip to main content
Email Password   helpLost your password?

Introduction

Some time ago, I had written an ASP.NET website showing some reports generated from a database. The reports contained tables, as well as dynamically generated graphs. To get a larger number of people to read the reports, it seemed like a good idea to send them as a weekly email newsletter. To be able to re-read the newsletter in a later stage, it was necessary to include the images, since they are changing over time. Embedding the images makes it also possible to send the mail to people that do not have access to the website.

This article shows a way to retrieve images from a web server and embed them into your email message.

Usage

This is how you can send a web page with the mailer class provided in this article:

// The contents that will be sent

Uri uri = new Uri("http://about.com/");

// Configuration of the email message

Fmd.Mail.WebpageMailer mailer = new Fmd.Mail.WebpageMailer();
mailer.SmtpServerName = "mail.somesmptserver.com";
mailer.Delay = 0;
mailer.MailMessage.From = new MailAddress("noreply@somedomain.com");
mailer.MailMessage.To.Add(new MailAddress("recipient@somedomain.com"));
mailer.MailMessage.Subject = "Automatic Mail Message " + 
                             DateTime.Now.ToShortDateString();
mailer.MailMessage.Priority = MailPriority.Normal;

// Sending the webpage

mailer.SendMailMessage(uri);

The main methods of the class

Sending the mail message

SendMailMessage is the main method in the class. It retrieves the contents of the web page to be sent. Next, it retrieves the images to embed. These parts are inserted into a mail message which is sent in the end.

public void SendMailMessage(Uri uri)
{
    // Retrieve the contents

    string htmlbody = GetBody(uri);
    
    // See what images there are to embed

    string modifiedbody;            
    List<linkedResource> foundResources;
    ExtractLinkedResources(uri, htmlbody, out modifiedbody, 
                           out foundResources);
    
    // Write the html to a memory stream

    MemoryStream stream = new MemoryStream();
    byte[] bytes = System.Text.Encoding.ASCII.GetBytes(modifiedbody);
    stream.Write(bytes, 0, bytes.Length);            
    stream.Position = 0;

    // Configure the mail so it contains the html page

    _mailMessage.Body = "This is a html mail - use an" + 
                        " email client that can read it";
    AlternateView altView = new AlternateView(stream, 
                  System.Net.Mime.MediaTypeNames.Text.Html);

    // Embed the images into the mail

    foreach (LinkedResource linkedResource in foundResources)
    {
        altView.LinkedResources.Add(linkedResource);
    }
    _mailMessage.AlternateViews.Add(altView);
    
    // Send the mail

    SmtpClient client = new SmtpClient(_smptServerName);
    client.Send(_mailMessage);
}

Filling the LinkedResource

This code snippet from ExtractLinkedResources shows how the images are embedded:

// Fill the linked resource

LinkedResource data = new LinkedResource(imageStream);

// Determine a name and set the media type of the linked resource

string generatedName = null;
if (contentType.ToLower().IndexOf("image/gif") >= 0)
{
    data.ContentType.MediaType = System.Net.Mime.MediaTypeNames.Image.Gif;
    generatedName = "image" + imageID.ToString() + ".gif";
}
else if (contentType.ToLower().IndexOf("image/jpeg") >= 0)
{
    data.ContentType.MediaType = System.Net.Mime.MediaTypeNames.Image.Jpeg;
    generatedName = "image" + imageID.ToString() + ".jpeg";
}

// it is something that I don't handle yet

if (generatedName == null)
    continue;

// Generate the linked resource for the image being embedded

string generatedSrc = "cid:" + generatedName;
data.ContentType.Name = generatedName;
data.ContentId = generatedName;
data.ContentLink = new Uri(generatedSrc);
linkedResources.Add(data); 

Getting a web page

This downloads the HTML contents:

public static string GetBody(Uri uri)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    
    // Set some reasonable limits on resources used by this request

    request.MaximumAutomaticRedirections = 4;
    request.MaximumResponseHeadersLength = 4;
    // Set credentials to use for this request.

    request.Credentials = CredentialCache.DefaultCredentials;
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    
    // Get the stream associated with the response.

    Stream receiveStream = response.GetResponseStream();

    // Pipes the stream to a higher level stream reader

    // with the required encoding format. 

    StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);

    string body = readStream.ReadToEnd();
    readStream.Close();

    response.Close();
    return body;
}

Glueing everything together

To make everything work together, there are a few things that need to be tackled. Since the images may be in some virtual directory on the web server, different from the page itself, their relative paths need to be changed. The program follows these steps to get everything together:

  1. Read the HTML body
  2. Analyze the HTML body to extract what images need to be retrieved
  3. Download the images, and make them available as a MemoryStream to embed into the mail message
  4. Modify the HTML so the image URLs are relative to the mail message instead of being relative to the web page
  5. Put everything into the mail message and send it away

Final remarks

This article can do two things for you. It can get you started when you want to send web pages as an email message, and the sample code may help you when you are struggling on how to embed images into a mail message. I hope you find it useful!

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralBackground-image cannot be displayed when I use css to control the url of background-image Pin
shuangking777
19:42 18 Feb '09  
GeneralLocalize mail Pin
sayyid.senux
22:09 13 Feb '09  
GeneralRe: Localize mail Pin
tracky
2:41 1 May '09  
GeneralRe: Localize mail Pin
tracky
3:02 1 May '09  
GeneralThanks Pin
herotayson
1:27 22 Aug '08  
GeneralCool Good Work Pin
jignesh_login
22:59 3 Jul '08  
GeneralModify version. Support SMTP Authentication Pin
Cool Dirty Boy
22:14 27 Oct '07  
GeneralUse of file:// protocol. Pin
rrodriguez
3:11 3 Aug '07  
GeneralRe: Use of file:// protocol. Pin
Five Minute Developer
8:29 4 Aug '07  
QuestionGet images from a SQL table Pin
sma1624
12:22 1 Mar '07  
Generalwant to help Pin
tariq developer
21:44 24 Jan '07  
AnswerRe: want to help Pin
Five Minute Developer
1:17 29 Jan '07  
GeneralHow to save/edit the email Pin
LittleGrass
17:18 22 Jan '07  
AnswerRe: How to save/edit the email Pin
Five Minute Developer
3:33 23 Jan '07  
GeneralHow can it have SMTP basic athentication? Pin
cornejoserrano
2:22 5 Jan '07  
GeneralRe: How can it have SMTP basic athentication? Pin
Five Minute Developer
11:18 5 Jan '07  
GeneralRe: How can it have SMTP basic athentication? Pin
Cool Dirty Boy
21:27 23 Oct '07  
AnswerRe: How can it have SMTP basic athentication? Pin
muhammedsimsek
2:10 14 May '08  
Generalcool Pin
Magician_Oz
12:37 28 Dec '06  
GeneralRe: cool Pin
Five Minute Developer
11:06 5 Jan '07  
GeneralThanks ! Pin
NinjaCross
2:10 28 Dec '06  
AnswerRe: Thanks ! Pin
Five Minute Developer
10:01 28 Dec '06  
GeneralRe: Thanks ! Pin
NinjaCross
8:03 30 Dec '06  
GeneralServer.Execute Pin
Gabe Wishnie
9:50 23 Dec '06  
GeneralRe: Server.Execute Pin
Five Minute Developer
1:16 24 Dec '06  


Last Updated 23 Dec 2006 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2009