In this article I will explain with an example, 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>
 
 
Generating the Unique Key for Cache
In the Page Load event of the Page a Unique Key for Cache is generated and is stored in a protected ViewState property.
C#
protected string Key
{
    get { return ViewState["Key"].ToString(); }
    set { ViewState["Key"] = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        this.Key = Guid.NewGuid().ToString();
        Cache[this.Key] = new List<HttpPostedFile>();
    }
}
 
VB.Net
Protected Property Key() As String
    Get
        Return ViewState("Key").ToString()
    End Get
    Set(value As String)
        ViewState("Key") = value
    End Set
End Property
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
    If Not IsPostBack Then
        Me.Key = Guid.NewGuid().ToString()
        Cache(Me.Key) = New List(Of HttpPostedFile)()
    End If
End Sub
 
Initially this article was using Session variable, but due to some reason Uploadify does not retain Session in Firefox browser hence I had to change the functionality to make use of Cache instead. But since Cache is not user specific i.e. shared across all users, we will need to generate a unique GUID Key for each user so that the Files can be uniquely identified.
 
 
Uploading multiple files as email attachments
To allow select and upload multiple files, I have made use of Uploadify jQuery plugin.
You will notice that I have used <% %> server side Tags <%=Key %> in the script, this is the ViewState protected Property (discussed earlier) which is used to pass the Cache Unique key to access the Cache variable during Upload and also during file removal.
<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': 'UploadCS.ashx',
            'folder': 'uploads',
            'multi': true,
            'auto': true,
            'scriptData': {key:'<%=Key %>'},
            '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 Cache. 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.Collections.Generic;
public class UploadCS : IHttpHandler {
    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/plain";
        context.Response.Expires = -1;
        try
        {
            List<HttpPostedFile> files = (List<HttpPostedFile>)context.Cache[context.Request.QueryString["key"]];
            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
  
    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        Try
            Dim files As List(Of HttpPostedFile) = DirectCast(context.Cache(context.Request.QueryString("key")), 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: "CS.aspx/RemoveFile",
            data: '{fileName: "' + fileName + '", key: "<%=Key %>" }',
            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 Cache variable where it was stored.
C#
[WebMethod]
public static void RemoveFile(string fileName, string key)
{
    List<HttpPostedFile> files = (List<HttpPostedFile>)HttpContext.Current.Cache[key];
    files.RemoveAll(f => f.FileName.ToLower().EndsWith(fileName.ToLower()));
}
 
VB.Net
<WebMethod()> _
Public Shared Sub RemoveFile(fileName As String, key As String)
    Dim files As List(Of HttpPostedFile) = DirectCast(HttpContext.Current.Cache(key), 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 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>)Cache[this.Key];
        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);
    }
    Cache.Remove(this.Key);
    Response.Redirect(Request.Url.AbsoluteUri);
}
 
VB.Net
Protected Sub btnSend_Click(sender As Object, e As EventArgs)
    Using mailMessage As 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) = DirectCast(Cache(Me.Key), 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 New SmtpClient()
        smtp.Host = "smtp.gmail.com"
        smtp.EnableSsl = True
        Dim NetworkCred As New System.Net.NetworkCredential()
        NetworkCred.UserName = mailMessage.From.Address
        NetworkCred.Password = "<Password>"
        smtp.UseDefaultCredentials = True
        smtp.Credentials = NetworkCred
        smtp.Port = 587
        smtp.Send(mailMessage)
    End Using
    Cache.Remove(Me.Key)
    Response.Redirect(Request.Url.AbsoluteUri)
End Sub
 
 
Screenshot
How to send email with Multiple Attachments in ASP.Net Website
 
 
Downloads