There are some scenarios where you want the flexibility to know when the email is checked by the user. You might have already experienced the same functionality when sending E-Cards to users which notifies that the receiver has checked the email.
In this post I will describe how you can easily create this functionality. The idea behind this technique is to append a very small image with the email. The image will have the querystring attached to it. When the client downloads the email the image request back to the server sending the querystring back which is later extracted and the database gets updated.
First let's see how a dummy email looks like:
<div>
This is some email that I am reading. This is a test email.
<img src='<%= GetImageUrl() %>' />
</div>
If you view the above code in the browser you will see the following:

The above image shows a little red dot but in real world applications you should use a smaller white image.
And here is the generated HTML for the above image.
<div>
This is some email that I am reading. This is a test email.
<img src='http://localhost:1404/WhiteImage.png?id=10369d25-77a3-438b-bc6c-a8b54c89dc64' />
</div>
The important point to note is the Guid at the end of the image which serves as an ID in the database. We can extract the Guid and update the field in the database which will indicate that the email has been read.
Now, we need to handle the request for the WhiteImage.png file. This can easily be performed by HttpHandler. Take a look at the following implementation.
public class EmailViewedNotificationHandler : IHttpHandler
{
private EmailNotificationService _emailNotificationService;
public EmailViewedNotificationHandler()
{
_emailNotificationService = new EmailNotificationService();
}
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
string id = context.Request.QueryString["id"] as String;
if (String.IsNullOrEmpty(id)) return;
Guid guid = new Guid(id);
_emailNotificationService.MarkEmailRead(guid);
// render the image!
MemoryStream ms = new MemoryStream();
Bitmap bitMap = new Bitmap(context.Request.PhysicalPath);
bitMap.Save(ms, ImageFormat.Png);
byte[] buffer = ms.ToArray();
context.Response.Clear();
context.Response.ContentType = "image/png";
context.Response.BinaryWrite(buffer);
context.Response.End();
}
}
The EmailNotificationService is responsible for marking the email as read. Currently, there is no implementation in the MarkEmailRead method but you can easily do this. Finally, add the configuration in the web.config file.
<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="WhiteImage.png" type="LearningWebApplication.EmailViewedNotificationHandler"/>
</httpHandlers>
Now, when you run the page the the WhiteImage.png request will be handled by the EmailViewedNotificationHandler handler. This will trigger the ProcessRequest method which will call the EmailViewedNotificationHandler's MarkAsRead method which will update the database and mark the email read.
NOTE: The method described above is not PERFECT! There are scenarios when the email client will ignore or block the images from downloading. In that case the above technique will not work.
[Download Sample]