A simple way to create a standard download link using generic handler in asp.net

In an ASP.Net website, sometimes the need arises that we have a resource write download link as a page or link within a write ups.

I have seen people cheap jerseys copying the link url and embed it directly an anchor tag, thought this works but I think it is not the best way to do it.

In this article which is going to be a wholesale nba jerseys two parts tutorials, I will show you how to create a download page in a standard way using Generic Handler in wholesale mlb jerseys part one, and how to separate free downloads from premium download using a custom built security.

Let’s start:

Create database, the file path and description etc will be saved cheap nfl jerseys in the database while the file itself in a folder.

Database

 The below screenshot shows the database structure.

 

The two stored procedures are below:

CREATE PROCEDURE [dbo].[UploadmyFile]

@file_title            nvarchar(50),
@file_description    nvarchar(1000),
@file_name            nvarchar(100),
@Ispremiun            BIT
AS

INSERT INTO dbo.asp_download
(
file_title,
file_description,
[file_name],
Ispremiun,
dateuploaded
)

VALUES
(
@file_title,
@file_description,
@file_name,
@Ispremiun,
GetDate()
)

GO
CREATE PROCEDURE [dbo].[GetDownloadFiles]

AS

SELECT file_title,file_description,[file_name] FROM dbo.asp_download

 

 

 

Create a new website, add a folder to the website called Hello uploads, a web form for resource upload, the markup should look like below in design view:

Code to upload the file

Let’s create a subroutine that saves to database as shown below:

 

Protected Sub SaveToDB(ByVal title As String, ByVal desc As String, _
      ByVal filepath As String, ByVal isprem As Boolean)
        'create connectionstring
        Dim constr As String = ConfigurationManager.ConnectionStrings("downloaddbConnectionString").ConnectionString
        Using con As SqlConnection = New SqlConnection(constr)
            Using cmd As SqlCommand = New SqlCommand()
                With cmd
                    .CommandText = "UploadmyFile"
                    .CommandType = Data.CommandType.StoredProcedure
                    .Parameters.AddWithValue("@file_title", title)
                    .Parameters.AddWithValue("@file_description", desc)
                    .Parameters.AddWithValue("@file_name", filepath)
                    .Parameters.AddWithValue("@Ispremiun", isprem)
                    .Connection = con
                    .Connection.Open()
                End With
                cmd.ExecuteNonQuery()
            End Using
        End Using
    End Sub

Code that goes to upload button clicked event below:

Protected Sub uploadButton_Click(sender As Object, e As System.EventArgs) Handles uploadButton.Click
        Dim ffolder As String = "~/uploads/"
        'Check if fileupload has file
        If Me.resourceFileUpload.HasFile Then
            'Get the full path of the file
            Dim savePath As String = ffolder & System.IO.Path. _
             GetFileName(Me.resourceFileUpload.PostedFile.FileName)

            'get the filename

            Dim fname As String = System.IO.Path. _
             GetFileName(Me.resourceFileUpload.PostedFile.FileName)
            'Upload the file
            resourceFileUpload.SaveAs(Server.MapPath(savePath))
            SaveToDB(Me.titleTextBox.Text.Trim, Me.descriptionTextBox.Text.Trim, fname, CBool(Me.ispremCheckBox.Checked))
            Me.titleTextBox.Text = "" : Me.descriptionTextBox.Text = "" : Me.ispremCheckBox.Checked = False

        End If
    End Sub

 

We have succeeded in uploading our resource, now we move to the download part.

Since we are going to use Generic Handler to handle our download request, lets add a new item to our website and choose generic  handler, rename it as appropriate for me I named it downloadhandler.ashx.

The code below goes to the generic handler page:

Public Class downloadhandler : Implements IHttpHandler

    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        Dim filename As String = context.Request.QueryString("file").ToString()
        fileDownload(filename, context.Server.MapPath("~/uploads/" + filename), context)
    End Sub

    Private Sub fileDownload(fileName As String, fileUrl As String, ByVal ct As HttpContext)

        ct.Response.Clear()

        Dim success As Boolean = ResponseFile(ct.Request, ct.Response, fileName, fileUrl, 1024000)
        If Not success Then
            ct.Response.Write("Downloading Error!")
        End If
        ct.Response.[End]()

    End Sub

    Public Shared Function ResponseFile(_Request As HttpRequest, _Response As HttpResponse, _fileName As String, _fullPath As String, _speed As Long) As Boolean
        Try
            Dim myFile As New FileStream(_fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
            Dim br As New BinaryReader(myFile)
            Try
                _Response.AddHeader("Accept-Ranges", "bytes")
                _Response.Buffer = False
                Dim fileLength As Long = myFile.Length
                Dim startBytes As Long = 0

                Dim pack As Integer = 10240
                '10K bytes
                Dim sleep As Integer = CInt(Math.Floor(CDbl(1000 * pack \ _speed))) + 1
                If _Request.Headers("Range") IsNot Nothing Then
                    _Response.StatusCode = 206
                    Dim range As String() = _Request.Headers("Range").Split(New Char() {"="c, "-"c})
                    startBytes = Convert.ToInt64(range(1))
                End If
                _Response.AddHeader("Content-Length", (fileLength - startBytes).ToString())
                If startBytes <> 0 Then
                    _Response.AddHeader("Content-Range", String.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength))
                End If
                _Response.AddHeader("Connection", "Keep-Alive")
                _Response.ContentType = "application/octet-stream"
                _Response.AddHeader("Content-Disposition", "attachment;filename=" & HttpUtility.UrlEncode(_fileName, System.Text.Encoding.UTF8))

                br.BaseStream.Seek(startBytes, SeekOrigin.Begin)
                Dim maxCount As Integer = CInt(Math.Floor(CDbl((fileLength - startBytes) \ pack))) + 1

                For i As Integer = 0 To maxCount - 1
                    If _Response.IsClientConnected Then
                        _Response.BinaryWrite(br.ReadBytes(pack))
                        Thread.Sleep(sleep)
                    Else
                        i = maxCount
                    End If
                Next
            Catch
                Return False
            Finally
                br.Close()
                myFile.Close()
            End Try
        Catch
            Return False
        End Try
        Return True
    End Function

    Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property
End Class

Add a new form that we futuro… be the download page and add the following markup:

 

<asp:DataList ID="downloadDataList" runat="server">
<HeaderTemplate>
    <table>
</HeaderTemplate>
<ItemTemplate>

        <tr>
            <td class="donwload-title"><asp:HyperLink ID="HyperLink2" Text='<%#Eval("file_title")%>' runat="server" CssClass="donwload-title"
                NavigateUrl='<%#ResolveUrl(String.Format("~/downloadhandler.ashx?file={0}",Eval("file_name")))%>' /></td>
                <td style="vertical-align: middle">
                                </td>
        </tr>

        <tr>
            <td class="download-description" colspan="2"><%#Eval("file_description")%></td>
        </tr>

        <tr>
            <td colspan="2" style="height:0.5px; background-color: #000066"></td>
        </tr>
         <tr>
            <td colspan="2" style="height:15px"></td>
        </tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:DataList>

 

Bind the datalist control as shown below:

 

 Protected Sub GetAllFiles()
        Dim constr As String = ConfigurationManager.ConnectionStrings("downloaddbConnectionString").ConnectionString
        Using con As SqlConnection = New SqlConnection(constr)

            Using cmd As SqlCommand = New SqlCommand()
                Using sda As SqlDataAdapter = New SqlDataAdapter(cmd)
                    With cmd
                        .CommandText = "GetDownloadFiles"
                        .CommandType = Data.CommandType.StoredProcedure
                        .Connection = con
                        .Connection.Open()
                    End With
                    Dim table As New DataTable
                    sda.Fill(table)

                    If table.Rows.Count > 0 Then
                        With Me.downloadDataList
                            .DataSource = table
                            .DataBind()
                        End With
                    End If
                End Using
            End Using

        End Using
    End Sub

    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        If Not Page.IsPostBack Then
            GetAllFiles()
        End If
    End Sub
End Clas

Run your application, upload one or more files then navigate the download page and clicked on the file title you should see something like below screenshot:

 

 

So it’s that easy to create a standard download link using generic handler in asp.net. in the cheap jerseys second part of this article we will see how we can protect downloads from a non –registered members using custom membership.

 

Facebook Comments

1 comment on “A simple way to create a standard download link using generic handler in asp.net”

Comments are closed.