In this article I will explain with an example, how to read emails from POP3 mail server in ASP.Net using C# and VB.Net.
This article makes use of the free open-source library OpenPop.Net which provides easy API to access and read emails from the POP3 mail Servers.
Download OpenPop.Net
You can download OpenPop.Net using the download link below.
HTML Markup
The following HTML Markup consists of an ASP.Net GridView with two BoundField columns and two TemplateField columns.
The first TemplateField column consists of a LinkButton control while second TemplateField column consists of an ASP.Net Repeater.
The body of the email is set to the hidden HTML SPAN element which will later use jQuery Dialog to display the body when LinkButton is clicked.
The GridView has been assigned with OnRowDataBound event handler and the DataKeyNames property has been set.
<asp:GridView ID="gvEmails" runat="server" OnRowDataBound="OnRowDataBound" DataKeyNames="MessageNumber"
AutoGenerateColumns="false">
<Columns>
<asp:BoundField HeaderText="From" DataField="From" HtmlEncode="false" />
<asp:TemplateField HeaderText="Subject">
<ItemTemplate>
<asp:LinkButton ID="lnkView" runat="server" Text='<%# Eval("Subject") %>' />
<span class="body" style="display: none">
<%# Eval("Body") %></span>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="Date" DataField="DateSent" />
<asp:TemplateField ItemStyle-CssClass="Attachments">
<ItemTemplate>
<asp:Repeater ID="rptAttachments" runat="server">
<ItemTemplate>
<asp:LinkButton ID="lnkAttachment" runat="server" OnClick="Download" Text='<%# Eval("FileName") %>' />
</ItemTemplate>
<SeparatorTemplate>
<br />
</SeparatorTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<div id="dialog" style="display: none">
<span id="body"></span>
<br />
<span id="attachments"></span>
</div>
Custom property class to hold the Email messages
The following two classes one for Email Message and one for Attachment created with custom properties which will be used to hold the fetched email messages.
Note: The classes are marked as Serializable to store the fetched email messages in a ViewState variable to retain data across PostBacks.
C#
[Serializable]
public class Email
{
public Email()
{
this.Attachments = new List<Attachment>();
}
public int MessageNumber { get; set; }
public string From { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public DateTime DateSent { get; set; }
public List<Attachment> Attachments { get; set; }
}
[Serializable]
public class Attachment
{
public string FileName { get; set; }
public string ContentType { get; set; }
public byte[] Content { get; set; }
}
VB.Net
<Serializable> _
Public Class Email
Public Sub New()
Me.Attachments = New List(Of Attachment)()
End Sub
Public Property MessageNumber As Integer
Public Property From As String
Public Property Subject As String
Public Property Body As String
Public Property DateSent As DateTime
Public Property Attachments As List(Of Attachment)
End Class
<Serializable> _
Public Class Attachment
Public Property FileName As String
Public Property ContentType As String
Public Property Content As Byte()
End Class
Namespaces
You will have to import the following namespaces.
C#
using OpenPop.Pop3;
using OpenPop.Mime;
using System.Linq;
VB.Net
Imports OpenPop.Pop3
Imports OpenPop.Mime
Imports System.Linq
Fetching the email messages from POP3 mail server and binding them to ASP.Net GridView
Inside the Page Load event, the GridView is populated with email messages by calling Read_Emails method.
Inside the Read_Emails method, first a connection is made to the GMAIL POP3 mail server using the UserName and Password.
Once the connection is successful, a loop will be executed over recent fetched email messages and properties are set fromMessage object to Email class and message body is set from MessagePart class.
Inside the loop, a check is performed to determine whether the email has any attachment and if found the attachments are added to Attachments property of the Email class.
Finally, the email is added to the ViewState property named Emails.
C#
protected List<Email> Emails
{
get { return (List<Email>)ViewState["Emails"]; }
set { ViewState["Emails"] = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
this.Read_Emails();
}
}
private void Read_Emails()
{
Pop3Client pop3Client;
if (Session["Pop3Client"] == null)
{
pop3Client = new Pop3Client();
pop3Client.Connect("pop.gmail.com", 995, true);
pop3Client.Authenticate("<Your Gmail Email>", "<Your Gmail Password>", AuthenticationMethod.TryBoth);
Session["Pop3Client"] = pop3Client;
}
else
{
pop3Client = (Pop3Client)Session["Pop3Client"];
}
int count = pop3Client.GetMessageCount();
this.Emails = new List<Email>();
int counter = 0;
for (int i = count; i >= 1; i--)
{
Message message = pop3Client.GetMessage(i);
Email email = new Email()
{
MessageNumber = i,
Subject = message.Headers.Subject,
DateSent = message.Headers.DateSent,
From = string.Format("<a href = 'mailto:{1}'>{0}</a>", message.Headers.From.DisplayName, message.Headers.From.Address),
};
MessagePart body = message.FindFirstHtmlVersion();
if (body != null)
{
email.Body = body.GetBodyAsText();
}
else
{
body = message.FindFirstPlainTextVersion();
if (body != null)
{
email.Body = body.GetBodyAsText();
}
}
List<MessagePart> attachments = message.FindAllAttachments();
foreach (MessagePart attachment in attachments)
{
email.Attachments.Add(new Attachment
{
FileName = attachment.FileName,
ContentType = attachment.ContentType.MediaType,
Content = attachment.Body
});
}
this.Emails.Add(email);
counter++;
if (counter > 2)
{
break;
}
}
gvEmails.DataSource = this.Emails;
gvEmails.DataBind();
}
VB.Net
Protected Property Emails() As List(Of Email)
Get
Return DirectCast(ViewState("Emails"), List(Of Email))
End Get
Set(value As List(Of Email))
ViewState("Emails") = value
End Set
End Property
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not Me.IsPostBack Then
Me.Read_Emails()
End If
End Sub
Private Sub Read_Emails()
Dim pop3Client As Pop3Client
If Session("Pop3Client") Is Nothing Then
pop3Client = New Pop3Client()
pop3Client.Connect("pop.gmail.com", 995, True)
pop3Client.Authenticate("<Your Gmail Email>", "<Your Gmail Password>", AuthenticationMethod.TryBoth)
Session("Pop3Client") = pop3Client
Else
pop3Client = DirectCast(Session("Pop3Client"), Pop3Client)
End If
Dim count As Integer = pop3Client.GetMessageCount()
Me.Emails = New List(Of Email)()
Dim counter As Integer = 0
For i As Integer = count To 1 Step -1
Dim message As Message = pop3Client.GetMessage(i)
Dim email As New Email()
email.MessageNumber = i
email.Subject = message.Headers.Subject
email.DateSent = message.Headers.DateSent
email.From = String.Format("<a href = 'mailto:{1}'>{0}</a>", message.Headers.From.DisplayName, message.Headers.From.Address)
Dim body As MessagePart = message.FindFirstHtmlVersion()
If body IsNot Nothing Then
email.Body = body.GetBodyAsText()
Else
body = message.FindFirstPlainTextVersion()
If body IsNot Nothing Then
email.Body = body.GetBodyAsText()
End If
End If
Dim attachments As List(Of MessagePart) = message.FindAllAttachments()
For Each attachment As MessagePart In attachments
Dim attachmentObj As New Attachment
attachmentObj.FileName = attachment.FileName
attachmentObj.ContentType = attachment.ContentType.MediaType
attachmentObj.Content = attachment.Body
email.Attachments.Add(attachmentObj)
Next
Me.Emails.Add(email)
counter += 1
If counter > 2 Then
Exit For
End If
Next
gvEmails.DataSource = Me.Emails
gvEmails.DataBind()
End Sub
Binding the Email Attachments to the Repeater inside ASP.Net GridView
Inside the OnRowDataBound event handler, the Attachments are fetched from the Emails property with the help of DataKeyNames property.
Finally, the list of Attachments is used to populate the Repeater control.
C#
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Repeater rptAttachments = (e.Row.FindControl("rptAttachments") as Repeater);
List<Attachment> attachments = this.Emails.Where(email => email.MessageNumber == Convert.ToInt32(gvEmails.DataKeys[e.Row.RowIndex].Value)).FirstOrDefault().Attachments;
rptAttachments.DataSource = attachments;
rptAttachments.DataBind();
}
}
VB.Net
Protected Sub OnRowDataBound(sender As Object, e As GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.DataRow Then
Dim rptAttachments As Repeater = TryCast(e.Row.FindControl("rptAttachments"), Repeater)
Dim attachments As List(Of Attachment) = Me.Emails.Where(Function(email) email.MessageNumber = Convert.ToInt32(gvEmails.DataKeys(e.Row.RowIndex).Value)).FirstOrDefault().Attachments
rptAttachments.DataSource = attachments
rptAttachments.DataBind()
End If
End Sub
Downloading the Email message Attachments
When the Download LinkButton is clicked, the attachment is fetched from the ViewState property named Emails and is sent to the Response for download using the BinaryWrite function.
C#
protected void Download(object sender, EventArgs e)
{
LinkButton lnkAttachment = (sender as LinkButton);
GridViewRow row = (lnkAttachment.Parent.Parent.NamingContainer as GridViewRow);
List<Attachment> attachments = this.Emails.Where(email => email.MessageNumber == Convert.ToInt32(gvEmails.DataKeys[row.RowIndex].Value)).FirstOrDefault().Attachments;
Attachment attachment = attachments.Where(a => a.FileName == lnkAttachment.Text).FirstOrDefault();
Response.AddHeader("content-disposition", "attachment;filename=" + attachment.FileName);
Response.ContentType = attachment.ContentType;
Response.BinaryWrite(attachment.Content);
Response.End();
}
VB.Net
Protected Sub Download(sender As Object, e As EventArgs)
Dim lnkAttachment As LinkButton = TryCast(sender, LinkButton)
Dim row As GridViewRow = TryCast(lnkAttachment.Parent.Parent.NamingContainer, GridViewRow)
Dim attachments As List(Of Attachment) = Me.Emails.Where(Function(email) email.MessageNumber = Convert.ToInt32(gvEmails.DataKeys(row.RowIndex).Value)).FirstOrDefault().Attachments
Dim attachment As Attachment = attachments.Where(Function(a) a.FileName = lnkAttachment.Text).FirstOrDefault()
Response.AddHeader("content-disposition", "attachment;filename=" + attachment.FileName)
Response.ContentType = attachment.ContentType
Response.BinaryWrite(attachment.Content)
Response.End()
End Sub
Viewing the Email Message body using jQuery UI Dialog
Inside the jQuery document.ready event handler, the every View LinkButton in the GridView has been assigned with a jQuery Click event handler.
When the View LinkButton is clicked, the email Subject, Body and Attachments are fetched from the GridView Row and displayed using the jQuery Dialog Modal Popup.
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.24/themes/smoothness/jquery-ui.css" />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.24/jquery-ui.min.js"></script>
<script type="text/javascript">
$(function () {
$("[id*=lnkView]").click(function () {
var subject = $(this).text();
var row = $(this).closest("tr");
$("#body").html($(".body", row).html());
$("#attachments").html($(".Attachments", row).html());
$("#dialog").dialog({
title: subject,
width: 600,
buttons: {
Ok: function () {
$(this).dialog('close');
}
}
});
return false;
});
});
</script>
Errors
Screenshot
Downloads