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

Tagged as

Go to top

ASP.Net MVC (2 & 3) - Tracking number of downloads

, 9 Jan 2012
Rate this:
Please Sign up or sign in to vote.
This tip explains how downloads could be tracked for any file in your website or another website

At times, you would wish to see the number of downloads your app (or any file) gets. The following tip discusses how this could be achieved. The intention is, if the user enters the url (for ex.) http://localhost:12345/downloads/CalendarControlSrc.zip, track the download and then return the file that the user requested. This is how you do them in ASP.Net MVC 3 (should also work in MVC 2).

The first step would be to access the database layer to save the count. I am not discussing this as its out of scope for this tip. As we intend to serve a file instead of a view, we just need to return a FileResult that takes in 3 parameters (other overloads are also available). The parameters expected are:

  • The url as received from Url.Content [Url.Content expects a virtual directory]
  • The application type of the file to be served. In this case it's a zip file and so the applicationType is "application/x-compressed"
	public ActionResult DownloadLink1()
	{
		// access the database layer and increment the counter to
		// indicate that SampleApp was downloaded
		string url = Url.Content("~/Content/downloads/CalendarControlSrc.zip");
		return File(url, "application/x-compressed");
	}

You may also wish to track the number of downloads you app (or some file) gets, when its hosted on another site. In that case, you cannot just use Url.Content as it expects a virtual path. So you will have to use the WebClient class to first download this file and then return it. In this case we use another overload of FileResult, as we are downloading the file and then presenting it to the user. This overload takes in a 3rd parameter which is the file name that the client sees while the download link is clicked (the client is free to change the name, of course). This overload of FileResult takes in a byte stream as the first parameter instead of a path returned by Url.Content. The first step just like the previous method would be to access the database layer to save the count.

	public ActionResult DownloadLink2()
	{
		// access the database layer and increment the counter to
		// indicate that SampleApp was downloaded

		byte[] file = null;
		using (var client = new WebClient())
		{
			file = client.DownloadData("http://www.codeproject.com/KB/webforms/Calendar/CalendarControlSource.zip");
		}
		return File(file, "application/x-compressed", "CalendarControlSource.zip");            
	}

Now, I will give an example as to how these action methods could be used. Lets assume these 2 action methods are in a controller called DownloadsController. We need to generate routes so that they could be added to various views. If you observe, unlike normal routes which doesn't have an extension in the url (in mvc), these url's need to have an extension so that the url indicates that it is indeed pointing to the path of the file about to be downloaded. So instead of just using Html.ActionLink we need to use Html.RouteLink, which generates url's depending on the format given in Global.asax.cs file. To achieve this, add the 2 routes to the Global.asax.cs file's RegisterRoutes method (text in bold).

 
	public static void RegisterRoutes(RouteCollection routes)
	{
		routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
		routes.MapRoute("DownloadRt1", "downloads/CalendarControlSrc.zip",
			new { controller = "Downloads", action = "DownloadLink1" });
 
		routes.MapRoute("DownloadRt2", "downloads/CalendarControlSource.zip",
			new { controller = "Downloads", action = "DownloadLink2" });
 
		routes.MapRoute(
			"Default", // Route name
			"{controller}/{action}/{id}", // URL with parameters
			new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
		);
	}
 

Finally, given below is a cshtml file that utilizes these 2 links

 
	@{
		ViewBag.Title = "Index";
	}
 
	<h2>Index</h2>
 
	@Html.RouteLink("download link 1", "DownloadRt1")
	<br />
	@Html.RouteLink("download link 2", "DownloadRt2")
 

The above Html.Routelink would generate the following links (assuming base url is http://localhost:12345) - http://localhost:12345/downloads/CalendarControlSrc.zip and http://localhost:12345/downloads/CalendarControlSource.zip. Html.RouteLink is a helper method that generates links using the route name (From Global.asax.cs passed in as the 2nd parameter. Clicking on these links would would call the database layer to log this download. Hope this tip was hepful!

License

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

Share

About the Author

Karthik. A
Software Developer
United States United States
Just another passionate software developer! I recently acquired my MCTS Wink | ;)
 
My latest contribution to the open source world is a blog engine written in MVC 3 - sBlog.Net. Check it out here. For the codeproject article regarding sBlog.Net click here!
 
I have recently (re)launched my web-site. Check it out at http://thekfactor.info!

Eventually, I have a blog under my own sub-domain. It is http://blog.thekfactor.info

Also check out my latest app - directory comparer [codeproject article and dedicated site] and my latest jquery plugin - partial collapsible panel!!!


All sites were developed in ASP.Net MVC 2 Smile | :)

Follow on   Twitter

Comments and Discussions

 
GeneralYou always have the option of improving upon a tip. Is this ... PinmemberKarthik. A17-Jan-12 5:08 
GeneralReason for my vote of 1 This implementation only seems to ma... PinmemberCUShane17-Jan-12 4:41 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 9 Jan 2012
Article Copyright 2012 by Karthik. A
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid