1. First create a new page for download processing, such as download.aspx, where there is nothing.
2. Add a Downloadhandler class, which inherits from the IHttpHandler interface, and can synchronize HTTP requests with a custom HTTP handler.
Copy Code code as follows:
public class Downloadhandler:ihttphandler
{
public void ProcessRequest (HttpContext context)
{
HttpResponse Response = context. Response;
HttpRequest Request = context. Request;
System.IO.Stream iStream = null;
byte[] buffer = new byte[10240];
int length;
Long dataToRead;
Try
{
string filename = Filehelper.decrypt (request["FN"]); Get file name by decrypting
string filepath = HttpContext.Current.Server.MapPath ("~/") + "files/" + filename; File path to download
IStream = new System.IO.FileStream (filepath, System.IO.FileMode.Open,
System.IO.FileAccess.Read, System.IO.FileShare.Read);
Response.Clear ();
dataToRead = Istream.length;
Long p = 0;
if (request.headers["Range"]!= null)
{
Response.statuscode = 206;
p = long. Parse (request.headers["Range"). Replace ("bytes=", ""). Replace ("-", ""));
}
if (P!= 0)
{
Response.AddHeader ("Content-range", "bytes" + p.tostring () + "-" + ((long) (dataToRead-1)). ToString () + "/" + datatoread.tostring ());
}
Response.AddHeader ("Content-length", ((Long) (datatoread-p)). ToString ());
Response.ContentType = "Application/octet-stream";
Response.AddHeader ("Content-disposition", "attachment; Filename= "+ System.Web.HttpUtility.UrlEncode (System.Text.Encoding.GetEncoding (65001). GetBytes (path.getfilename (filename)));
Istream.position = p;
dataToRead = datatoread-p;
while (dataToRead > 0)
{
if (response.isclientconnected)
{
Length = istream.read (buffer, 0, 10240);
Response.OutputStream.Write (buffer, 0, length);
Response.Flush ();
Buffer = new byte[10240];
dataToRead = Datatoread-length;
}
Else
{
dataToRead =-1;
}
}
}
catch (Exception ex)
{
Response.Write ("Error:" + ex.) message);
}
Finally
{
if (IStream!= null)
{
Istream.close ();
}
Response.End ();
}
}
public bool IsReusable
{
get {return true;}
}
}
3. This involves a file name plus decryption problem, is to prevent the file specific name exposed in the status bar, so add a Filehelper class, the code is as follows:
Copy Code code as follows:
public class Filehelper
{
public static string Encrypt (string filename)
{
byte[] buffer = HttpContext.Current.Request.ContentEncoding.GetBytes (filename);
Return Httputility.urlencode (convert.tobase64string (buffer));
}
public static string Decrypt (String encryptfilename)
{
byte[] buffer = convert.frombase64string (encryptfilename);
return HttpContext.Current.Request.ContentEncoding.GetString (buffer);
}
}
Use the BASE64 code to encrypt and decrypt the file name.
4. On the web.config, add the HttpHandlers node as follows:
Copy Code code as follows:
<system.web>
<add verb= "*" path= "download.aspx" type= "Downloadhandler"/>
</system.web>
5. Now create a new ASPX page to download the file:
The Default.aspx code is as follows:
Default.aspx
Copy Code code as follows:
<%@ Page language= "C #" autoeventwireup= "true" codefile= "Default.aspx.cs" inherits= "_default"%>
<! DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 transitional//en" "Http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">
<title> File Download </title>
<body>
<form id= "Form1" runat= "Server" >
<div>
<asp:hyperlink id= "link" runat= "server" text= "File Download" ></asp:HyperLink>
</div>
</form>
</body>
The Default.aspx.cs code is as follows:
Default.aspx.cs
Copy Code code as follows:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class _default:system.web.ui.page
{
protected void Page_Load (object sender, EventArgs e)
{
String url = Filehelper.encrypt ("Designpattern.chm");
Link. NavigateUrl = "~/download.aspx?fn=" + url;
}
}