Menus

Friday, December 14, 2012

Send email with Multiple Attachments in ASP.Net Website

In this article I will explain how to attach multiple files and send email like GMAIL in ASP.Net using jQuery Uploadify Plugin.

HTML Markup
Below is the HTML Markup which is nothing but a simple form to send email.
<table>
<tr><td>To:</td><td><asp:TextBox ID="txtTo" runat="server"></asp:TextBox></td></tr>
<tr><td>Subject:</td><td><asp:TextBox ID="txtSubject" runat="server"></asp:TextBox></td></tr>
<tr><td>Body:</td><td><asp:TextBox ID="txtBody" runat="server" TextMode="MultiLine"></asp:TextBox></td></tr>
<tr><td></td><td><asp:FileUpload ID="FileUpload1" runat="server"/></td></tr>
<tr><td></td><td><table id="attachedfiles"></table></td></tr>
<tr><td></td><td><asp:Button ID="btnSend" runat="server" Text="Send" OnClick="btnSend_Click"/></td></tr>
</table>
  Uploading multiple files as email attachments
To allow select and upload multiple files, I have made use of Uploadify jQuery plugin
<link rel="Stylesheet" type="text/css" href="CSS/uploadify.css" />
<script type="text/javascript" src="scripts/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="scripts/jquery.uploadify.js"></script>
<script type="text/javascript">
    $(function () {
        $("[id*=FileUpload1]").fileUpload({
            'uploader': 'scripts/uploader.swf',
            'cancelImg': 'images/cancel.png',
            'buttonText': 'Attach Files',
            'script': 'Upload.ashx',
            'folder': 'uploads',
            'multi': true,
            'auto': true,
            'onSelect': function (event, ID, file) {
                $("#attachedfiles tr").each(function () {
                    if ($("td", this).eq(0).html() == file.name) {
                        alert(file.name + " already uploaded.");
                        $("[id*=FileUpload1]").fileUploadCancel(ID);
                        return;
                    }
                });
            },
            'onComplete': function (event, ID, file, response, data) {
                $("#attachedfiles").append("<tr><td>" + file.name + "</td><td><a href = 'javascript:;'>[x]</a></td></tr>");
            }
        });
    });
</script>
The files are uploaded via Generic Handler Upload.ashx. I am storing the uploaded files in Session. Also the uploaded files are dynamically displayed on the page
C#
<%@ WebHandler Language="C#" Class="UploadCS" %>
using System;
using System.Web;
using System.IO;
using System.Web.SessionState;
using System.Collections.Generic;
public class UploadCS : IHttpHandler, IRequiresSessionState {
    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/plain";
        context.Response.Expires = -1;
        try
        {
            List<HttpPostedFile> files = (List<HttpPostedFile>)context.Session["Files"];
            HttpPostedFile postedFile = context.Request.Files["Filedata"];
            files.Add(postedFile);
            string filename = postedFile.FileName;
            context.Response.Write(filename);
            context.Response.StatusCode = 200;
        }
        catch (Exception ex)
        {
            context.Response.Write("Error: " + ex.Message);
        }
    }
    public bool IsReusable {
        get {
            return false;
        }
    }
}
VB.Net
<%@ WebHandler Language="VB" Class="UploadVB" %>
Imports System
Imports System.Web
Imports System.IO
Imports System.Collections.Generic
Public Class UploadVB : Implements IHttpHandler, IRequiresSessionState
  
    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        Try
            Dim files As List(Of HttpPostedFile) = DirectCast(context.Session("Files"), List(Of HttpPostedFile))
            Dim postedFile As HttpPostedFile = context.Request.Files("Filedata")
            files.Add(postedFile)
            Dim filename As String = postedFile.FileName
            context.Response.Write(filename)
            context.Response.StatusCode = 200
        Catch ex As Exception
            context.Response.Write("Error: " + ex.Message)
        End Try
    End Sub
    Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property
End Class
 
Removing Attached files using jQuery AJAX
I have also added functionality to remove files like we have in GMAIL browser. To achieve this I have made use of jQuery AJAX and ASP.Net Page Methods
<script type="text/javascript">
$("#attachedfiles a").live("click", function () {
    var row = $(this).closest("tr");
    var fileName = $("td", row).eq(0).html();
    $.ajax({
        type: "POST",
        url: "Default.aspx/RemoveFile",
        data: '{fileName: "' + fileName + '" }',
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function () { },
        failure: function (response) {
            alert(response.d);
        }
    });
    row.remove();
});
</script>
The above JavaScript function makes call to a WebMethod defined below which deletes the file from the Session variable where it was stored.
C#
[WebMethod]
public static void RemoveFile(string fileName)
{
    List<HttpPostedFile> files = (List<HttpPostedFile>)HttpContext.Current.Session["Files"];
    files.RemoveAll(f => f.FileName.ToLower().EndsWith(fileName.ToLower()));
}
VB.Net
<WebMethod()> _
Public Shared Sub RemoveFile(fileName As String)
    Dim files As List(Of HttpPostedFile) = DirectCast(HttpContext.Current.Session("Files"), List(Of HttpPostedFile))
    files.RemoveAll(Function(f) f.FileName.ToLower().EndsWith(fileName.ToLower()))
End Sub
 
Sending the email with multiple attachment

Finally here’s the code to send email using GMAIL account.
C#
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        Session["Files"] = new List<HttpPostedFile>();
    }
}
protected void btnSend_Click(object sender, EventArgs e)
{
    using (MailMessage mailMessage = new MailMessage())
    {
        mailMessage.From = new MailAddress("user@gmail.com");
        mailMessage.Subject = txtSubject.Text.Trim();
        mailMessage.Body = txtBody.Text.Trim();
        mailMessage.IsBodyHtml = true;
        mailMessage.To.Add(new MailAddress(txtTo.Text.Trim()));
        List<HttpPostedFile> files = (List<HttpPostedFile>)Session["Files"];
        foreach (HttpPostedFile file in files)
        {
            mailMessage.Attachments.Add(new Attachment(file.InputStream, Path.GetFileName(file.FileName), file.ContentType));
        }
        SmtpClient smtp = new SmtpClient();
        smtp.Host = "smtp.gmail.com";
        smtp.EnableSsl = true;
        System.Net.NetworkCredential NetworkCred = new System.Net.NetworkCredential();
        NetworkCred.UserName = mailMessage.From.Address;
        NetworkCred.Password = "<Password>";
        smtp.UseDefaultCredentials = true;
        smtp.Credentials = NetworkCred;
        smtp.Port = 587;
        smtp.Send(mailMessage);
    }
    Response.Redirect(Request.Url.AbsoluteUri);
}
VB.Net
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
    If Not IsPostBack Then
        Session("Files") = New List(Of HttpPostedFile)
    End If
End Sub
Protected Sub btnSend_Click(ByVal sender As Object, ByVal e As EventArgs)
    Dim mailMessage As MailMessage = New MailMessage
    mailMessage.From = New MailAddress("user@gmail.com")
    mailMessage.Subject = txtSubject.Text.Trim
    mailMessage.Body = txtBody.Text.Trim
    mailMessage.IsBodyHtml = True
    mailMessage.To.Add(New MailAddress(txtTo.Text.Trim))
    Dim files As List(Of HttpPostedFile) = CType(Session("Files"), List(Of HttpPostedFile))
    For Each file As HttpPostedFile In files
        mailMessage.Attachments.Add(New Attachment(file.InputStream, Path.GetFileName(file.FileName), file.ContentType))
    Next
    Dim smtp As SmtpClient = New SmtpClient
    smtp.Host = "smtp.gmail.com"
    smtp.EnableSsl = True
    Dim NetworkCred As System.Net.NetworkCredential = New System.Net.NetworkCredential
    NetworkCred.UserName = mailMessage.From.Address
    NetworkCred.Password = "<Password>"
    smtp.UseDefaultCredentials = True
    smtp.Credentials = NetworkCred
    smtp.Port = 587
    smtp.Send(mailMessage)
    Response.Redirect(Request.Url.AbsoluteUri)
End Sub
  Screenshot
Send email with multiple attachments like GMAIL in ASP.Net
 

No comments:

Post a Comment