miércoles, 2 de noviembre de 2011

ASP.NET - Creando un cliente de correo POP3 en pagina aspx

aspnet_pop3Por si alguien está interesado en crear un cliente de correo Pop3 desde ASP.NET, vamos a ver cómo lo desarrollamos.
Antes que nada debo decirles que he probado muchos componentes free del mercado y la verdad que no me han gustado, luego he conocido Lumisoft.net, el cual me ha encantado y es con quien actualmente trabajo.
Lumisoft tiene un componente .NET que me permite gestionar de manera eficiente mis correos desde una página aspx, este componente lo pueden hallar en http://www.lumisoft.ee/lsWWW/ENG/index_eng.aspx?type=main, pero al final de este post estoy adjuntando un archivo adjunto con un proyecto completo de muestra, así que no se preocupen por hallar el componente.
Los datos que necesito para conectarme a mi correo son:
1.- Servidor de correo
2.- Puerto a usar
3.- Cuenta de correo
4.- Contraseña
Entonces, vamos a crear una pequeña aplicación que me permita ingresar esos datos y luego de una autenticación exitosa, vamos a recuperar los emails en una colección genérica para luego mostrarlos en un control repeater.
Código aspx:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Cliente de correo POP3 en pagina aspx</title>
    <link href="StyleSheet1.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <table style="width: 200px; margin: auto auto">
            <tr>
                <th>
                    Cliente POP3
                </th>
            </tr>
            <tr>
                <td style="white-space: nowrap">
                    <asp:Label ID="Label1" runat="server" Text="Servidor de correo:"></asp:Label>
                    <br />
                    <asp:TextBox ID="txtEmailServer" runat="server" TabIndex="1"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td>
                    <asp:Label ID="Label2" runat="server" Text="Puerto:"></asp:Label>
                    <br />
                    <asp:TextBox ID="txtPort" Width="50px" runat="server" TabIndex="2"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td>
                    <asp:Label ID="Label3" runat="server" Text="Correo:"></asp:Label>
                    <br />
                    <asp:TextBox ID="txtEmail" runat="server" TabIndex="3"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td>
                    <asp:Label ID="Label4" runat="server" Text="Contraseña:"></asp:Label>
                    <br />
                    <asp:TextBox ID="txtPassword" TabIndex="4" runat="server" TextMode="Password"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td style="vertical-align: bottom;">
                    <asp:ImageButton ID="imgLogin" runat="server" ImageUrl="~/images/go.png" />
                </td>
            </tr>
        </table>
        <div style="margin-top: 20px">
            <asp:Repeater ID="rptPOP3" runat="server">
                <HeaderTemplate>
                    <table style="width: 100%">
                        <tr>
                            <th>
                                UID
                            </th>
                            <th>
                                Remite
                            </th>
                            <th>
                                Asunto
                            </th>
                            <th>
                                Adjuntos
                            </th>
                            <th>                                
                            </th>
                        </tr>
                </HeaderTemplate>
                <ItemTemplate>
                    <tr>
                        <td style="width: 30px;">
                            <%# Eval("uid").ToString().Remove(1,35) %>                        </td>
                        <td>
                            <%# Eval("from")%>                        </td>
                        <td>
                            <%# Eval("subject")%>                            <br />
                            <span style="color: gray"><%# Eval("body")%></span>
                        </td>
                        <td style="width: 5%; text-align: center">
                            <%# HaveAttachments(Eval("Attachments"))%>                        </td>
                        <td style="width: 5%">
                            <asp:ImageButton ID="imgDelete" CommandName="Delete" 
                                CommandArgument='<%# Eval("uid") %>'
                                OnClientClick="if(!confirm('Está seguro que desea eliminar el correo?')) return false;"
                                ImageUrl="images/delete.png" runat="server" />
                        </td>
                    </tr>
                </ItemTemplate>
                <FooterTemplate>
                    </table>
                </FooterTemplate>
            </asp:Repeater>
        </div>

    </div>
    </form>
</body>
</html>

Código VB.NET:
Imports LumiSoft.Net.POP3.Client
Imports LumiSoft.Net.Mail

Public Class _Default
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    End Sub

    Protected Sub imgLogin_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles imgLogin.Click

        GetEmails()

    End Sub

    Private Sub GetEmails()
        Dim pop3 As New POP3_Client

        'Conectándose al servidor de correo
        pop3.Connect(txtEmailServer.Text, txtPort.Text, False)

        'Autenticando al usuario
        pop3.Authenticate(txtEmail.Text, txtPassword.Text, True)

        'creo una colección para guardar los correos
        Dim ItemEmails As New List(Of ItemEmail)
        Try

            For Each message As POP3_ClientMessage In pop3.Messages
                Dim mime As Mail_Message = Mail_Message.ParseFromByte(message.MessageToByte())

                If mime.From IsNot Nothing Then
                    Dim mail As New ItemEmail()

                    'Guardo los datos del email
                    mail.Subject = mime.Subject
                    mail.UID = message.UID
                    mail.From = mime.From(0).Address
                    mail.Body = mime.BodyText

                    'reviso si hay archivos adjuntos
                    If (mime.Attachments.Length() > 0) Then

                        'Guardo los archivos adjuntos en una carpeta de mi aplicación
                        For XAttach As Integer = 0 To mime.Attachments.Length - 1
                            Dim guid As String = Utils.GenerateUniqueGUID()
                            Dim FileName As String = mime.Attachments(XAttach).ContentDisposition.Param_FileName
                            IO.File.WriteAllBytes(Utils.GetApplicationPhysicalPath() & "Attachments\" & _
                            guid, DirectCast(mime.Attachments(XAttach).Body, LumiSoft.Net.MIME.MIME_b_SinglepartBase).Data)

                            mail.AddAttachment(New ListItem(FileName, guid))
                        Next

                    End If

                    ItemEmails.Add(mail)

                End If

            Next
        Catch x As Exception
            'x.Message
        Finally
            pop3.Dispose()
        End Try

        rptPOP3.DataSource = ItemEmails
        rptPOP3.DataBind()

        For Each email As ItemEmail In ItemEmails

            'desde aquí puedes insertar los datos en tu base de datos
            'email.Subject
            'email.Body

            'obtienes los archivos
            If Not IsNothing(email.Attachments) Then
                For Each att As ListItem In email.Attachments
                    'att.Text, 
                    'Attribute.value
                Next
            End If

        Next

    End Sub

    Protected Function HaveAttachments(ByVal obj As Object) As String
        If IsNothing(obj) Then
            Return String.Empty
        Else
            Return "<img src='images/attachment.png' />"
        End If
    End Function

    Protected Sub rptPOP3_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.RepeaterCommandEventArgs) Handles rptPOP3.ItemCommand

        If e.CommandName.ToString = "Delete" And e.CommandArgument.ToString <> "" Then

            Dim uid As String = e.CommandArgument.ToString
            Dim pop3 As New POP3_Client

            'Conectándose al servidor de correo
            pop3.Connect(txtEmailServer.Text, txtPort.Text, False)

            'Autenticando al usuario
            pop3.Authenticate(txtEmail.Text, txtPassword.Text, True)

            'Elimino el correo
            pop3.Messages.Item(uid).MarkForDeletion()
            pop3.Dispose()

            'recupero nuevamente la lista de correos
            GetEmails()

        End If

    End Sub

End Class
Luego de ingresar los datos, presionen el botón VER, para que se cargue el repeater… verán algo como esta imagen:
aspnet_pop3_2
Analicen el código, es muy simple… inclusive estoy verificando si cada correo tiene archivos adjuntos… y estoy descargando los archivos adjuntos en una carpeta llamada attachments. No se olviden que si desean descargar los archivos en una carpeta, deben darle permiso de escritura al usuario NETWORK SERVICE en dicha carpeta.

Espero que les sea de utilidad Guiño

5 comentarios:

Anónimo dijo...

tienes mas hecho? No se como hacer la visualizacion de cada correo individual.

Aparte sabes como abrir archivos eml con este dll?

GIANCARLO dijo...

Amigo estoy provando tu ejemplo antes me visualizaba los correos ahora ya no pero si hay correos en mi emial.
que esta pasando o la dll es de prueba
saludos

Segundo Serrano dijo...

Hola GIANCARLO,
deberìa funcionarte sin problemas... verifica que tu còdigo no ha sido alterado o has ingresado incorrectamente el correo o tal vez la contraseña es otra.

Saludos

SebaPHI dijo...

buenas, se que es un tema viejo pero tandras algun ejemplo donde baje solo los correos si leer?

Muchas gracias

Anónimo dijo...

Brother los adjuntos llegan sin extension como puedo hacer que lleguen con la extension original? Saludos