Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

ASP.NET: Downloading files from a UNC share

0.00/5 (No votes)
14 Feb 2017 1  
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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here