Click here to Skip to main content
Click here to Skip to main content

Tagged as

Go to top

ASP.NET: Downloading files from a UNC share

, 14 Feb 2012
Rate this:
Please Sign up or sign in to vote.
Implementing a cross-browser solution for downloading files from a UNC share in ASP.NET applications

Table of Contents

The Scenario

I was working recently in an intranet application that had a download page. The output HTML was similar to the following:

<li><a class="download" 
href="\\MYSERVER\reports 2011\report1.zip" title="Report 1">Report 1</a></li>
<li><a class="download" 
href="\\MYSERVER\reports 2011\report2.zip" title="Report 2">Report 2</a></li>
<li><a class="download" 
href="\\MYSERVER\reports 2011\report 3.zip" title="Report 3">Report 3</a></li>
<li><a class="download" 
href="\\MYSERVER\reports 2011\report 4.zip" title="Report 4">Report 4</a></li>
<li><a class="download" 
href="\\MYSERVER\reports 2011\report 5&6.zip" title="Report 5&6">Report 5&6</a></li>

This was working fine in IE9, but not in other browsers. There was no action using Google Chrome, and using Firefox there was an error (HTTP Error 400 – Bad Request).

I tried to convert the file path to a file URI but it didn’t fix it. It continued to work on Internet Explorer only.

<li><a class="download" 
href="file://MYSERVER/reports 2011/report1.zip" title="Report 1">Report 1</a></li>
<li><a class="download" 
href="file://MYSERVER/reports 2011/report2.zip" title="Report 2">Report 2</a></li>
<li><a class="download" 
href="file://MYSERVER/reports 2011/report 3.zip" title="Report 3">Report 3</a></li>
<li><a class="download" 
href="file://MYSERVER/reports 2011/report 4.zip" title="Report 4">Report 4</a></li>
<li><a class="download" 
href="file://MYSERVER/reports 2011/report 5&6.zip" title="Report 5&6">Report 5&6</a></li>

The solution was to create a custom ASP.NET download page. I also used jquery on the client side.

Step 1: Using jquery on the Client Side

The first step was to add an event handler to the download links. The request URI is encoded and is sent as a parameter to the download page. Creating an hidden iframe and setting the src attribute with the download link allows the file to be downloaded asynchronously.

$("a.download").bind("click", function (e) {
    e.preventDefault();
    var requestedFile = encodeURIComponent($(this).attr('href'));

    var iframe = document.createElement("iframe");
    iframe.src = 'Download.aspx?file=' + requestedFile;
    iframe.style.display = "none";
    document.body.appendChild(iframe); // triggers download page
});

Make sure you use encodeURIComponent function to encode special characters in the filename.

Step 2: Create an ASP.NET Download Page

This is the source code of the download page:

protected void Page_Load(object sender, EventArgs e)
{
    try
    {
        string requestFile = Request.QueryString["file"];

        if(string.IsNullOrEmpty(requestFile))
        {
            throw new FileNotFoundException("File to download cannot be null or empty");
        }

        // Get file name from URI string in C#
        // http://stackoverflow.com/a/1105614
        var uri = new Uri(requestFile);
        string filename = Path.GetFullPath(uri.LocalPath);
        var fileInfo = new FileInfo(filename);

        if(!fileInfo.Exists)
        {
            throw new FileNotFoundException("File to download was not found", filename);
        }

        // get content type based on file extension. Example:
        // http://stackoverflow.com/a/691599
        Response.ContentType = GetContentType(fileInfo.Extension);

        Response.AddHeader("Content-Disposition", 
                           "attachment; filename=\"" + fileInfo.Name + "\"");
        Response.WriteFile(fileInfo.FullName);
        Response.End();
    }
    catch(ThreadAbortException)
    {
        // ignore exception
    }
    catch(FileNotFoundException ex)
    {
        Response.StatusCode = (int) System.Net.HttpStatusCode.NotFound;
        Response.StatusDescription = ex.Message;
    }
    catch(Exception ex)
    {
        Response.StatusCode = (int) System.Net.HttpStatusCode.InternalServerError;
        Response.StatusDescription = 
        string.Format("Error downloading file: {0}", ex.Message);
    }
}

Some notes:

This is necessary in order to make the download work with a UNC share (\\MYSERVER\….) or a file URI (file://….)

    var uri = new Uri(requestFile);
    string filename = Path.GetFullPath(uri.LocalPath);

To avoid filename truncating, it’s necessary to wrap the filename with quotes:

Response.AddHeader("Content-Disposition", 
                       "attachment; filename=\"" + fileInfo.Name + "\"");

References

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Rui Jarimba
Software Developer (Senior)
Ireland Ireland
My name is Rui Jarimba and I was born in Madeira island, Portugal and I currently live in Dublin, Ireland.
 
I’m working as a .NET software developer since 2005.
 
Some of my professional interests are:
 
Web development using .NET Framework;
Service Oriented Architecture (SOA);
Database development and modelling;
Web accessibility, usability, and standards;
Software Architecture;
Design Patterns
Follow on   Twitter   LinkedIn

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 15 Feb 2012
Article Copyright 2012 by Rui Jarimba
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid