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 InterfaceThe
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 toIDownloadService.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:
- 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. - The user clicks the link, which activates the
Download.aspx
page. - The
Page_Load
event handler in theDownload.aspx
page extracts the Type and Ref elements from the query string, instantiates the designated type and calls theIDownloadService.SendItemToBrowser
method, passing the Ref element as theitemID
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.
Comments