Manual File Downloads In ASP.NET

Getting Started

First, I've defined an IDownloadService interface that is implemented by the class that formats the plain text files and generates the HTML content (the RozpravaRaw class - see below):

Public Interface IDownloadService
  Sub SendItemToBrowser( _
    ByVal itemID As String, _
    ByVal response As HttpResponse)
End Interface
The itemID argument identifies what should be downloaded. In the case of transcript files, it is the file name. The response argument references the current HttpResponse instance.

Second, I've implemented a generic Download.aspx page, which expects two QueryString variables passed to it:

  • The Type variable contains a type name of a class that would handle the download by implementing the IDownloadService interface.
  • The Ref variable is the name of an item to be downloaded (i.e. a transcript file), which is passed as the itemID argument in the call to IDownloadService.SendItemToBrowser.

Third, I've added the actual IDownloadService implementation to a RozpravaRaw class ("rozprava" is a Slovak term for "debate"), which already handled other aspects of the transcript files processing:

Public Class RozpravaRaw
Implements IDownloadService
...
Private Sub SendItemToBrowser( _
    ByVal itemID As String, _
    ByVal response As System.Web.HttpResponse) _
    Implements IDownloadService.SendItemToBrowser
    ' Generate content dynamically (Response.Write etc.)
End Sub
End Class

The processing goes as follows:

  1. The user views a list of transcripts in her browser. Each transcript file link is generated using the Download.aspx page, for example
    Download.aspx?Type=NRozprava.RozpravaRaw&Ref=XXX030909101042000_030909101500000.txt.
  2. The user clicks the link, which activates the Download.aspx page.
  3. The Page_Load event handler in the Download.aspx page extracts the Type and Ref elements from the query string, instantiates the designated type and calls the IDownloadService.SendItemToBrowser method, passing the Ref element as the itemID argument:

Private Sub Page_Load( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Try
    ...
    ' Parse the query string - "Ref" and "Type" variables are mandatory.
    Dim TypeName, Ref As String
    Me.ParseQueryString(TypeName, Ref)
    ' Create an IDownloadService dynamicaly and delegate to it.
    Dim Service As IDownloadService = CreateDownloadService(TypeName)
    Service.SendItemToBrowser(Ref, Response)
Catch ex As Exception
    SetError(ex.ToString())
    Trace.Warn(ex.ToString())
    Diagnostics.Trace.WriteLine(ex.ToString())
End Try
End Sub
Private Sub ParseQueryString( _
ByRef typeName As String, _
ByRef ref As String)
typeName = Request.QueryString("Type")
If typeName Is Nothing Then
    typeName = String.Empty
End If
' If typeName contains a space, it is just HTML-encoded "+" sign,
' which the CLR uses when naming nested classes.
typeName = typeName.Replace(" "c, "+"c)
ref = Request.QueryString("Ref")
If ref Is Nothing Then
    ref = String.Empty
End If
End Sub
Private Shared Function CreateDownloadService( _
ByVal typeName As String) As IDownloadService
Try
    Dim Assm As System.Reflection.Assembly = System.Reflection.Assembly.GetExecutingAssembly()
    Return DirectCast(Assm.CreateInstance(typeName, True), IDownloadService)
Catch ex As Exception
    Throw New ApplicationException( _
    String.Format("Unknown request ({0}).",
typeName), ex)
End Try
End Function

I've designed it this way because, besides the dynamic transcript file download, the application had to support downloading other file types (namely .DOC and .MP3 files). This way, the download link is always the same and the actual download content generation logic is placed within the particular IDownloadService implementation.

You might also like...

Comments

About the author

Palo Mraz

Palo Mraz United States

I live in Slovakia with my wife, two sons (fulltime), one daughter (occasionally) and a dog. I've been doing Microsoft Windows development since 1988; primarily in VB. I'm a big fan of the MS .N...

Interested in writing for us? Find out more.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” - Martin Fowler