In this article I will explain how to read emails from POP3 mail server using the free open source library OpenPop.Net. This library provides you very easy API to access and read emails from the POP3 mail Servers. For this article I’ll be using GMAIL POP3 mail Server
Download OpenPop.Net
You can download OpenPop.Net using the download link below
HTML Markup
Here I have used ASP.Net GridView control to display the email messages. I am keeping the body of the email in a hidden HTML SPAN as I’ll later use jQuery Dialog to display the body when subject is clicked.
<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>
Namespaces
You will have to import the following namespaces
C#
using OpenPop.Pop3;
using OpenPop.Mime;
using System.Linq;
Custom property class to hold the Email messages
You will have to create the following custom property class whose object will be used to hold the fetched email message. I have created two classes one for Email Message and one for Attachment.
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; }
}
Note: I have marked these classes as Serializable as I’ll store the fetched email messages in a ViewState variable to retain data across PostBacks.
Fetching the email messages from POP3 mail server and binding them to ASP.Net GridView
Below is the code to fetch the email messages from GMAIL POP3 mail server.
1. I am connecting to the POP3 mail server using the GMAIL UserName and Password.
2. Once connected I am looping fetching top three recent email messages and adding them to the ViewState property Emails whose type is of the custom property classEmail we created earlier.
3. While running the loop I am also checking if there’s any attachment in the email and if one is found I am adding the attachments too Attachments property of the Emailclass whose type is of the custom property class Attachment we created earlier.
C#
protected List<Email> Emails
{
get { return (List<Email>)ViewState["Emails"]; }
set { ViewState["Emails"] = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (!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("youremail@gmail.com", "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();
}
The following screenshots displays the ASP.Net GridView bound with the fetched email messages. You will notice that the email attachment files are being displayed.
Binding the Email Attachments to the Repeater inside ASP.Net GridView
I have used the ASP.Net Repeater control inside the TemplateField of ASP.Net GridView to bind the email attachments. I am binding the Repeater on theOnRowDataBound event of GridView.
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();
}
}
Downloading the Email message Attachments
When the name of the Attachment File is clicked it executes the following event handler which fetches the attachment from the ViewState property Emails and then sends it for download.
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();
}
Viewing the email message body Client Side using jQuery UI Dialog
Client side I have the following click event handler trigger when the Subject is clicked. It fetches the email Subject, Body and Attachments and displays it in jQuery UI dialog as shown in the following screenshot
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.9/jquery-ui.js" type="text/javascript"></script>
<link href="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.9/themes/start/jquery-ui.css"
rel="stylesheet" type="text/css" />
<script type="text/javascript">
$("[id*=lnkView]").live("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,
buttons: {
Ok: function () {
$(this).dialog('close');
}
}
});
return false;
});
</script>
Verified..
0 comments:
Post a Comment