Answered by:
How to Download a file with a hyperlink

Question
-
User-1772541395 posted
I have been all over the net reading samples to this, they are not for ASP 2.0 or the example code given does not work.
So could someone PLEASE put this simple thing in black and white?
Assuming you have created a blank aspx lets say Downloading.aspx and are going to hyperlink from links.aspx... and all your files that you want available for the client to download are stored in a public folder on your domain lets say mydomain/downloadstuff.
1. Example of hyperlink to use on links.aspx
2. Code to use on downloading.aspx (assume to use the octet thing that supports all types of files) and does the code go in downloading.aspx or downloading.aspx.vb
thanks,
Brad Zynda
Saturday, January 12, 2008 8:17 PM
Answers
-
User2022958948 posted
Hi,
There is a sample as below. link.aspx is listing all of the files avaliable in folder and click the hyperlink in link.aspx will trigger downloading this file in downloading.aspx.
link.aspx:
using System.IO; protected void Page_Load(object sender, EventArgs e) { DirectoryInfo di = new DirectoryInfo(Server.MapPath("~/downloadstuff")); int i = 0; foreach(FileInfo fi in di.GetFiles()) { HyperLink HL = new HyperLink(); HL.ID = "HyperLink" + i++; HL.Text = fi.Name; HL.NavigateUrl = "downloading.aspx?file="+fi.Name; Page.Controls.Add(HL); Page.Controls.Add(new LiteralControl("<br/>")); } }
downloading.aspx:
using System.IO; using System.Threading; protected void Page_Load(object sender, EventArgs e) { string filename = Request["file"].ToString(); fileDownload(filename, Server.MapPath("~/downloadstuff/"+filename)); } private void fileDownload(string fileName, string fileUrl) { Page.Response.Clear(); bool success = ResponseFile(Page.Request, Page.Response, fileName, fileUrl, 1024000); if (!success) Response.Write("Downloading Error!"); Page.Response.End(); } public static bool ResponseFile(HttpRequest _Request, HttpResponse _Response, string _fileName, string _fullPath, long _speed) { try { FileStream myFile = new FileStream(_fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); BinaryReader br = new BinaryReader(myFile); try { _Response.AddHeader("Accept-Ranges", "bytes"); _Response.Buffer = false; long fileLength = myFile.Length; long startBytes = 0; int pack = 10240; //10K bytes int sleep = (int)Math.Floor((double)(1000 * pack / _speed)) + 1; if (_Request.Headers["Range"] != null) { _Response.StatusCode = 206; string[] range = _Request.Headers["Range"].Split(new char[] { '=', '-' }); startBytes = Convert.ToInt64(range[1]); } _Response.AddHeader("Content-Length", (fileLength - startBytes).ToString()); if (startBytes != 0) { _Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength)); } _Response.AddHeader("Connection", "Keep-Alive"); _Response.ContentType = "application/octet-stream"; _Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(_fileName, System.Text.Encoding.UTF8)); br.BaseStream.Seek(startBytes, SeekOrigin.Begin); int maxCount = (int)Math.Floor((double)((fileLength - startBytes) / pack)) + 1; for (int i = 0; i < maxCount; i++) { if (_Response.IsClientConnected) { _Response.BinaryWrite(br.ReadBytes(pack)); Thread.Sleep(sleep); } else { i = maxCount; } } } catch { return false; } finally { br.Close(); myFile.Close(); } } catch { return false; } return true; }
Hope it helps.
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, January 15, 2008 2:22 AM
All replies
-
User312496708 posted
The link the hyperlink to the virtual path of the physical file. so ur link should be something like
mydomain/downloadstuff/filename.txt
Now when the user clicks the link the file will be downloaded itself.
Sunday, January 13, 2008 2:33 AM -
User-1016451685 posted
if you are giving a simple hyperlink to download the File(whatever..) Just put the link to that file i.e. Download. it will be down loaded autometically in virtual server. in case of you are not using hyperlink i.e. using Button or ImageButton then code will be on Downloading.aspx.vb and it should be look like Response.Redirect("myDomain/DownloadStuff/DownloadIT.exe").. I wish it may help you.Sunday, January 13, 2008 10:13 AM -
User-122480877 posted
I think you may be after something a bit different
Lets say you have 10 download links on one page Called "Products.aspx".
Lets make this our item list
-
item_1
-
item_2
-
item_3
-
item_4
-
item_5
-
item_6
-
item_7
-
item_8
-
item_9
-
item_10
Ok now think of those as links. If you click a link that is a download we are taken to a page lets call it DownLoad.aspx
For each item you can have its own script query that looks lik this "Download.aspx?i=1" and Download.aspx?i=2 and so on. To do this would only take a few minutes you would store the info in an xml with the item id and the virtual path to the actual download destination.
Once you have done this you will find it really easy to build.
If this is what your looking at doing let me know.. [:D]
Sunday, January 13, 2008 10:53 AM -
-
User-1772541395 posted
With all the talk of right and wrong ways of doing this I dont know which way to go, I know the simple call of having the browser throw up the download box works, here is an example:
<a href="http://www.mydomain.com/Downloads/MyFile.zip">Download MyFile.zip</a>, (put this where ever you want the hyperlink)
But I have read that this is no longer the way to do it, that you should call through a seperate page using the write method.
So what is the right way to be doing it and what is an example?
Sunday, January 13, 2008 1:21 PM -
User2022958948 posted
Hi,
There is a sample as below. link.aspx is listing all of the files avaliable in folder and click the hyperlink in link.aspx will trigger downloading this file in downloading.aspx.
link.aspx:
using System.IO; protected void Page_Load(object sender, EventArgs e) { DirectoryInfo di = new DirectoryInfo(Server.MapPath("~/downloadstuff")); int i = 0; foreach(FileInfo fi in di.GetFiles()) { HyperLink HL = new HyperLink(); HL.ID = "HyperLink" + i++; HL.Text = fi.Name; HL.NavigateUrl = "downloading.aspx?file="+fi.Name; Page.Controls.Add(HL); Page.Controls.Add(new LiteralControl("<br/>")); } }
downloading.aspx:
using System.IO; using System.Threading; protected void Page_Load(object sender, EventArgs e) { string filename = Request["file"].ToString(); fileDownload(filename, Server.MapPath("~/downloadstuff/"+filename)); } private void fileDownload(string fileName, string fileUrl) { Page.Response.Clear(); bool success = ResponseFile(Page.Request, Page.Response, fileName, fileUrl, 1024000); if (!success) Response.Write("Downloading Error!"); Page.Response.End(); } public static bool ResponseFile(HttpRequest _Request, HttpResponse _Response, string _fileName, string _fullPath, long _speed) { try { FileStream myFile = new FileStream(_fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); BinaryReader br = new BinaryReader(myFile); try { _Response.AddHeader("Accept-Ranges", "bytes"); _Response.Buffer = false; long fileLength = myFile.Length; long startBytes = 0; int pack = 10240; //10K bytes int sleep = (int)Math.Floor((double)(1000 * pack / _speed)) + 1; if (_Request.Headers["Range"] != null) { _Response.StatusCode = 206; string[] range = _Request.Headers["Range"].Split(new char[] { '=', '-' }); startBytes = Convert.ToInt64(range[1]); } _Response.AddHeader("Content-Length", (fileLength - startBytes).ToString()); if (startBytes != 0) { _Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength)); } _Response.AddHeader("Connection", "Keep-Alive"); _Response.ContentType = "application/octet-stream"; _Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(_fileName, System.Text.Encoding.UTF8)); br.BaseStream.Seek(startBytes, SeekOrigin.Begin); int maxCount = (int)Math.Floor((double)((fileLength - startBytes) / pack)) + 1; for (int i = 0; i < maxCount; i++) { if (_Response.IsClientConnected) { _Response.BinaryWrite(br.ReadBytes(pack)); Thread.Sleep(sleep); } else { i = maxCount; } } } catch { return false; } finally { br.Close(); myFile.Close(); } } catch { return false; } return true; }
Hope it helps.
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, January 15, 2008 2:22 AM -
User-1772541395 posted
Well all of these work but I was looking for the proper way of going about this and have chosen Vince Xu's way. It seems to be the most secure and allows for tracking what is downloaded and I can easily add in a way to get the clients ip.
Thanks guys
Thursday, January 17, 2008 12:43 PM -
User1262397796 posted
This may be a newbie comment but do you just copy the raw code detailed here into respective files links and downloads then once upload just navigate to links.aspx?
Well all of these work but I was looking for the proper way of going about this and have chosen Vince Xu's way. It seems to be the most secure and allows for tracking what is downloaded and I can easily add in a way to get the clients ip.
Thanks guys
Sunday, January 20, 2008 5:42 PM -
User-1772541395 posted
I believe you should put the code into the links.aspx.vb and the same for the downloads putting it directly into the aspx page should cause some errors. The vb page should be created at the same time you create the aspx.
Sunday, January 20, 2008 6:36 PM