locked
How to Download a file with a hyperlink RRS feed

  • 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

    1. item_1
    2. item_2
    3. item_3
    4. item_4
    5. item_5
    6. item_6
    7. item_7
    8. item_8
    9. item_9
    10. 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