Secure Downloading in ASP.NET
The Advantages of Downloading with FileUp
- The files to download do not have to be in a browsable location on the server.
- The path to the file only exists in the server-side code, which helps protect sensitive
information from end-users.
- Files can be downloaded from any location on the Web server, from a file server,
or from a database.
- FileUp allows you to limit the bandwidth used for downloads per connection and per server.
The behavior of a download is heavily browser-dependent. The only way to ensure
that your application works as desired is to extensively test on many different
browser platforms. Alternatively, you can use a client-side control such as SoftArtisans XFileto handle your downloads.
|
Top
The TransferFile Method
FileUp's TransferFile
method downloads a file from server to browser. TransferFile
takes
the parameter FileName
- the path and name of the file to download.
The path must be a physical path, but you can set FileName
to virtual
path using MapPath().
TransferFile with a physical path |
C# |
FileUp.TransferFile("c:\\folder\\sample.doc"); |
VB.NET |
FileUp.TransferFile("c:\folder\sample.doc") |
|
TransferFile with a virtual path |
C# |
FileUp.TransferFile(Page.MapPath(Application["vroot"].ToString() +
"/sample.doc"));
|
VB.NET |
FileUp.TransferFile(Page.MapPath(Application("vroot").ToString() + _ "/sample.doc"))
|
|
The NTFS permissions on the file to be downloaded must be set to allow "Read" access
to the identity under which FileUp is running.
To download from a database, use FileUp's TransferBlob
method.
Top
Setting Response Headers
To let the browser know how to handle a download, you must include three response
headers in the download script:
- Content-type
The file's MIME content-type, for example, "application/msword"
.
- Content-disposition
If the file's content-disposition is set to "inline"
, the file will
open in the browser. Depending on browser security settings, the user may be prompted
with an "open or save" dialog. The user can choose to save to the file system, or
open the file directly in the browser, if the browser supports a plug-in associated
with that file type.
If content-disposition is set to "attachment"
, the browser will open
a dialog that asks whether the user wants to open or save the downloaded file. In
this situation, the user can either save the file to the file system or open the
file in it's native application.
The content-disposition header also includes the file name.
- Content-size
To display an accurate progress indicator when downloading, the browser has to know
how many bytes to expect. The content-size header provides this information. In
the following examples, we use the .NET System.IO.FileInfo class to obtain the size
of the file and set it in the content-size header.
Top
Downloading Large Files
Response buffering is enabled by default in ASP.NET. This is not an ideal situation
for downloading large files as the entire file will be placed in memory before it
is sent to the browser. This may result in memory spikes on the server or the appearance
that the browser is hanging, while it waits for the Response from the server.
It is recommended that you disable Response buffering on the page level on those
pages that use FileUp to download files. This can be done as follows:
C# |
Response.Buffer = false; |
VB.NET |
Response.Buffer = false |
Add this line near the top of your response output logic. It must occur before any
HTML or Response.Write statements. When you disable Response buffering, remove any
instances of Response.Clear or Response.Flush from your code as they will cause
your script to fail.
Download and Open in the Browser
A download script should not include Response.Write statements or any
HTML. If the response includes anything other than the file and response headers,
the downloaded file will be corrupted.
|
The HTTP response's content-disposition header lets the browser know whether to
open the downloaded file in the browser, or it's native application. This header
also tells the browser the name of the downloaded file. If content-disposition is
set to "inline"
- as in the following example - the file will open
in the browser, provided browser security settings allow this type of action.
C# - Download and Open in Browser |
private void DownloadFile() { //--- Disable Response buffering if downloading
a large file. Response.Buffer=False;
//--- Declare the FileUp object FileUp fileDownload = null;
try { //--- Instantiate
the FileUp object fileDownload = new FileUp (Context);
//--- Set the path
and filename of the file
//--- we're going to transfer. string strFilePath;
strFilePath = "C:\\folder\\sample.doc"; string strFileName = "sample.doc";
//--- Set response
headers. //--- FileUp is responsible for
reading the file
//--- and sending the raw bytes //--- down to the client through
the Response.
//--- In order for the browser //--- to handle the data properly,
the context of
//--- the anonymously streaming
bytes //--- needs to be established.
//--- This is done with HTTP response
headers.
//--- ContentType tells the browser
what kind of file is coming. //--- application/msword is a Microsoft
Word document Response.ContentType = "application/msword";
//--- Content-Disposition
tells the browser how to
//--- handle the file, and what
the name //--- of the file is. The "inline"
option tells the browser
//--- to open the Word doc in the
browser plug-in. Response.AddHeader("Content-Disposition",
"inline;filename=\""
+
strFileName + "\""); Response.AddHeader("Content-Length",
new
System.IO.FileInfo(strFilePath).Length.ToString());
//--- Call FileUp.TransferFile
and pass the full file path //--- to begin downloading the file fileDownload.TransferFile(strFilePath); Page.Response.SuppressContent =
true;
} catch (Exception ex) { //--- If an exception
is caught, display a message Page.Response.ClearHeaders(); Page.Response.Write("<b>An
exception has occurred " + "when
downloading the file</b> <br>" +
ex.Message); } finally { //--- Always call
FileUp.Dispose in the finally block if(fileDownload != null) { fileDownload.Dispose(); fileDownload
= null; } } }
|
VB.NET - Download and Open in Browser |
Private Sub DownloadFile()
'--- Disable Response buffering if downloading
a large file. Response.Buffer = False
'--- Declare the FileUp object Dim fileDownload As FileUp
Try '--- Instantiate
the FileUp object fileDownload = New FileUp (Context)
'--- Set the path
and filename of the file
'--- we're going to transfer. Dim strFilePath As String
strFilePath = "C:\folder\sample.doc" Dim strFileName As String = "sample.doc"
'--- Set response
headers. '--- FileUp is responsible for reading
the file
'--- and sending the raw bytes '--- down to the client through
the Response. '--- In order for the browser '--- to handle the data properly,
the context of
'--- the anonymously streaming bytes '--- needs to be established.
'--- This is done with HTTP response
headers.
'--- ContentType tells the browser
what kind of file is coming. '--- application/msword is a Microsoft
Word document Response.ContentType = "application/msword"
'--- Content-Disposition
tells the browser how to
'--- handle the file, and what the
name '--- of the file is. The "inline"
option tells the browser
'--- to open the Word doc in the
browser plug-in. Response.AddHeader("Content-Disposition",
_ "inline;filename="""
+ strFileName + """") Response.AddHeader("Content-Length",
_ New
System.IO.FileInfo(strFilePath).Length.ToString())
'--- Call FileUp.TransferFile
and pass the full file path '--- to begin downloading the file fileDownload.TransferFile(strFilePath) Page.Response.SuppressContent =
true
Catch ex As System.Exception '--- If an exception
is caught, display a message Page.Response.ClearHeaders() Page.Response.Write("<b>An
exception has occurred " + _ "when
downloading the file</b><br>" + _ ex.Message)
Finally '--- Always call
FileUp.Dispose in the finally block If Not (fileDownload Is Nothing)
Then fileDownload.Dispose() fileDownload
= Nothing End If End Try
End Sub
|
Top
Download and Open in the Native Application
A download script should not include Response.Write statements or any
HTML. If the response includes anything other than the file and response headers,
the downloaded file will be corrupted.
|
The HTTP response's content-disposition header lets the browser know whether to
open the downloaded file in the browser, or open the file in the file's native application.
If content-disposition is set to "attachment"
- as in the following
example - the browser will display a dialog that asks the user to open or save the
file. Choosing "open" will result in the file being opened in its native application.
Choosing "save" allows the user to save the file to the file system.
This header also tells the browser the name of the downloaded file.
C# - Download and Open in the Native Application |
private void DownloadFile() { //--- Disable Response buffering if downloading
a large file. Response.Buffer=False;
//--- Declare the FileUp object FileUp fileDownload = null;
try { //--- Instantiate
the FileUp object fileDownload = new FileUp (Context);
//--- Set the path
and filename of the file
//--- we're going to transfer. string strFilePath; strFilePath = "C:\\folder\\sample.doc"; string strFileName = "sample.doc";
//--- Set response
headers. //--- FileUp is responsible for
reading the file
//--- and sending the raw bytes //--- down to the client through
the Response.
//--- In order for the browser //--- to handle the data properly,
the context of
//--- the anonymously streaming
bytes //--- needs to be established.
//--- This is done with HTTP response
headers.
//--- ContentType tells the browser
what kind of file is coming. //--- application/msword is a Microsoft
Word document Response.ContentType = "application/msword";
//--- Content-Disposition
tells the browser how to
//--- handle the file, and what
the name //--- of the file is. The "attachment"
option tells the browser
//--- to open the Word doc in a
new instance of Microsoft Word,
//--- not in the browser Word plug-in Response.AddHeader("Content-Disposition",
"attachment;filename=\""
+ strFileName + "\""); Response.AddHeader("Content-Length",
new
System.IO.FileInfo(strFilePath).Length.ToString());
//--- Call FileUp.TransferFile
and pass the full file path //--- to begin downloading the file fileDownload.TransferFile(strFilePath); Page.Response.SuppressContent =
true;
} catch (Exception ex) { //--- If an exception
is caught, display a message Page.Response.ClearHeaders(); Page.Response.Write("<b>An
exception has occurred " +
"when
downloading the file</b> <br>" +
ex.Message); } finally { //--- Always call
FileUp.Dispose in the finally block if(fileDownload != null) { fileDownload.Dispose(); fileDownload
= null; } } }
|
VB.NET - Download and Open in the Native Application |
Private Sub DownloadFile()
'--- Disable Response buffering if downloading
a large file. Response.Buffer = False
'--- Declare the FileUp object Dim fileDownload As FileUp
Try '--- Instantiate
the FileUp object fileDownload = New FileUp (Context)
'--- Set the path
and filename of the file
'--- we're going to transfer. Dim strFilePath As String
strFilePath = "C:\folder\sample.doc" Dim strFileName As String = "sample.doc"
'--- Set response
headers. '--- FileUp is responsible for reading
the file.
'--- and sending the raw bytes '--- down to the client through
the Response.
'--- In order for the browser '--- to handle the data properly,
the context of
'--- the anonymously streaming bytes '--- needs to be established.
'--- This is done with HTTP response
headers.
'--- ContentType tells the browser
what kind of file is coming. '--- application/msword is a Microsoft
Word document Response.ContentType = "application/msword"
'--- Content-Disposition
tells the browser how to
'--- handle the file, and what the
name '--- of the file is. The "attachment"
option tells
'--- the browser to open the Word
doc '--- in a new instance of Microsoft
Word,
'--- not in the browser Word plug-in. Response.AddHeader("Content-Disposition",
_ "attachment;filename="""
+ strFileName + """") Response.AddHeader("Content-Length",
_ New
System.IO.FileInfo(strFilePath).Length.ToString())
'--- Call FileUp.TransferFile
and pass the full file path '--- to begin downloading the file fileDownload.TransferFile(strFilePath) Page.Response.SuppressContent =
true
Catch ex As System.Exception '--- If an exception
is caught, display a message Page.Response.ClearHeaders() Page.Response.Write("<b>An
exception has occurred " + _ "when
downloading the file</b><br>" + _ ex.Message)
Finally '--- Always call
FileUp.Dispose in the finally block If Not (fileDownload Is Nothing)
Then fileDownload.Dispose() fileDownload
= Nothing End If End Try
End Sub
|
Top
Copyright © 2010 SoftArtisans, Inc. All rights reserved.