Secure Downloading in ASP.NET



The Advantages of Downloading with FileUp
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 TransferFilemethod 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 TransferBlobmethod.

Top


Setting Response Headers

To let the browser know how to handle a download, you must include three response headers in the download script:

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.