Instructor-led Online Courses in ASP.NET Core and Angular by Bipin Joshi. Read more...
Registration open for ASP.NET Core and Angular instructor-led online courses. Courses conducted by Bipin Joshi on weekends. Click here for more details.

Use HTML5 download attribute to download a URL

The anchor element allows you to render a hyperlink to a resource using its href attribute. There is a lesser known attribute of the anchor element - download - that can come handy in certain situations. The download attribute instructs the browser to download the resource as mentioned in the href attribute. Moreover, you can also specify the default file name for the download.

If you worked with file downloading with ASP.NET before you are probably aware of Content-Disposition header that can be used to specify the default file name in the browser's Save As dialog. The download attribute introduced in HTML5 comes handy in the following situations :

  • You want the user to download a resource rather than navigating to it.
  • You want to assign some default file name for the file being downloaded.

Note that the download attribute works only for same origin URLs.

Suppose you are rendering a few hyperlinks in the browser and each link points to an image file. When you click on such a link the browser will navigate to the image file rather than prompting you to download it. What if you want to explicitly tell the browser not to navigate to the image and instead download it? That's where download attribute of HTML5 can come handy. Have a look at the following markup :

<a href="computer.png" download>
  Download File
</a>

<a href="computer.png" download="PC.png">
  Download File
</a>

The first hyperlink points to Computer.png and also has download attribute. In this case download attribute doesn't have any specific value. Its presence tells the browser to download the image file rather than navigating to it.

The second hyperlink sets the download attribute to PC.png. In this case the browser shows the download dialog and also sets the default file name to PC.png.

The above example used image files as the target of the hyperlink. But you can use any other resource such as an HTML file. An example follows :

<a href="~/MonthlyReport" download="MonthlyReport.html">Download</a>

Here, the href points to a razor page named MonthlyReport.cshtml and the download sets the default download file name to MonthlyReport.html. So, when you click on this link the browser won't navigate to the razor page, rather it will prompt the use to download it's response.

Let's try to use the download attribute in a simple ASP.NET Core razor page.

The above razor page displays a list of image files from Images folder placed under wwwroot. Each link points to the image file under consideration using its href attribute. You can then download the images by clicking on their links.

This is how the physical image files are placed :

Ok. Add a razor page (Index.cshtml) under the pages folder and write the following code in its OnGet() method.

public class IndexModel : PageModel
{

    public IEnumerable<string> ImageFiles { get; set; }

    public void OnGet([FromServices]IHostingEnvironment env)
    {
        string imagePath = 
$"{env.WebRootPath}\\images";

        this.ImageFiles = Directory.GetFiles
(imagePath).Select(fileName => Path.GetFileName(fileName));
    }
}

The above code shows the Index page model class with ImageFiles property. This property is assigned a value in the OnGet() method. The OnGet() method receives IHostingEnvironment object using [FromServices] DI attribute. The code then gets a list of files from the Images folder. This is done using Directory.GetFiles() method. Note that the Select() method picks only the file names skipping the folder information. We do this because we don't need complete physical path of these files.

Then go to the Index.cshtml file and write the following code :

@foreach (string file in Model.ImageFiles)
{
    <h2>
        <a href="~/images/@file" 
download='@(System.IO.Path.GetFileNameWithoutExtension(file) 
+ 
DateTime.Now.ToString("ddMMyyyy") 
+ 
System.IO.Path.GetExtension(file))'>
            @file
        </a>
    </h2>
}

Notice the code marked in bold letters. The code iterates through all the image files from the ImageFiles page model property. Every iteration renders a hyperlink whose href points to the corresponding image file from the /wwwroot/images folder. The download attribute sets a different name to be displayed in the file download dialog. The download name adds a date stamp to the original file name. This is achieved using GetFileNameWithoutExtension() and GetExtension() methods.

Now run the Index page in the browser and try clicking on any of the links. You will be prompted with a file download dialog.

So far so good.

Downloading canvas image

The download attribute can also be used in situations where some kind of content (such as images, CSV, or XML) is being generated in the browser dynamically. Suppose you are using HTML5 canvas to draw some graphics in the browser. You want to allow the end user to download the canvas content as an image file. How would you do that? The download attribute along with data URLs can be used to accomplish this task. Let's see how.

Assume that you have the <canvas> element placed in the razor page as shown below :

<canvas id="canvas" width="500" height="500"></canvas>
...
<a id="download" href="#" 
onclick="Download()">Download Canvas Image</a>
...

The <canvas> element allows you to render graphics. The download hyperlink placed below the canvas allows you to download the canvas graphics. The Download() JavaScript function is responsible for doing this job for us. It is shown below :

function Download() {
    var canvas = document.getElementById('canvas');
    var cxt = canvas.getContext('2d');
    cxt.fillRect(100, 100, 200, 200);
    cxt.clearRect(120, 120, 160, 160);

    downloadLink = document.getElementById('download');
    downloadLink.href = canvas.toDataURL();
    downloadLink.download = "MyCanvas.png";
}

The Download() function first draws a rectangle on the canvas and then clears a region from the rectangle. We won't go into any details of canvas element here.

Then we grab the reference to the download anchor element and set its href and download properties. The href property is set to a data URLntaining the base64 encoded e data. This is done using the toDataURL() method of  the canvas. The download property is set to MyCanvas.png.

The following figure shows a sample run of the above code :

Downloading a CSV file

Another use of the download attribute could be when you want the user to download dynamically generated CSV or XML data. Suppose you have a table displayed on a web page like this :

When you click on the Download Table link you want export the table data into CSV and then prompt the user to download the CSV file. You can accomplish this task with a dash of jQuery code as shown below :

$(document).ready(function () { 
    $("#downloadTable").click(function () {
        var csv = $("#empTable")
.table2CSV({ delivery: 'value' });
        downloadLink = document.getElementById
('downloadTable');
        downloadLink.href = 
'data:text/csv;charset=UTF-8,' + 
encodeURIComponent(csv);
        downloadLink.download = "EmployeeTable.csv";
    });
});

The above code wires the click event handler of the Download Table link. Upon clicking the link the code converts the table data into CSV. This is done using a jQuery plugin - table2CSV. We grab the data in a variable. Next, we set the href property of the link to URL data Notice how the data URL is formed using the encodeURIComponent() method and text/csv content type. Moreover, we also set the download property of the hyperlink to EmployeeTable.csv. This way the download dialog will have the default file name of EmployeeTable.csv.

That's it for now! Keep coding !!


Bipin Joshi is a software consultant, trainer, author and yoga mentor having 22+ years of experience in software development. He also conducts online courses on ASP.NET MVC, ASP.NET Core and Design Patterns. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced the Yoga way of life he also teaches Ajapa Yoga to interested individuals. To know more about him click here.

Get connected : Twitter  Facebook  Google+  LinkedIn

Posted On : 26 March 2018


Tags : ASP.NET ASP.NET Core MVC .NET Framework C# Visual Studio