Search code examples
sql-servervb.netfile-uploadhttphandlerplupload

HTTPHandler in VB.net for uploading files using Plupload


I have built working VB.net code that uploads multiple images to the server using Plupload. I am using an HTTPHandler (FileUpload.ashx) to do the uplading and want to add a SQL Statement that will insert each of the images File Names to my SQL Database. I have tried just adding the SQL to the Handler, but when I do I get 4 database entries for each iamge that is uploaded. I really dont understand why and need some guidance. Thanks for your time in advance.

Pertainant HANDLER code:

Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest

    Dim chunk As Integer = If(context.Request("chunk") IsNot Nothing, Integer.Parse(context.Request("chunk")), 0)
    Dim fileName As String = If(context.Request("name") IsNot Nothing, context.Request("name"), String.Empty)
    Dim fileUpload As HttpPostedFile = context.Request.Files(0)

    Dim uploadPath = context.Server.MapPath("Upload")
    Using fs = New FileStream(Path.Combine(uploadPath, fileName), If(chunk = 0, FileMode.Create, FileMode.Append))
        Dim buffer = New Byte(fileUpload.InputStream.Length - 1) {}
        fileUpload.InputStream.Read(buffer, 0, buffer.Length)

        fs.Write(buffer, 0, buffer.Length)
    End Using
    context.Response.ContentType = "text/plain"
    context.Response.Write("Success")

EXP: SQL insert

        Dim conn As SqlClient.SqlConnection = New SqlClient.SqlConnection(DBCONN)
    Dim command As SqlClient.SqlCommand = New SqlClient.SqlCommand("W2_InsertPhoto " & fileName, conn)
    Dim rs As SqlClient.SqlDataReader
    conn.Open()
    rs = command.ExecuteReader()
    rs.Close()
    rs = Nothing
    conn.Close()
    conn = Nothing

Solution

  • If you are using chunks then make sure that you fire your SQL aster the last chunk has been saved

    For example.

      chunk = If(context.Request("chunk") IsNot Nothing, Integer.Parse(context.Request("chunk")), 0)
      chunks = If(context.Request("chunks") IsNot Nothing, Integer.Parse(context.Request("chunks")) - 1, 0) 
    
    
     If (chunk = chunks) Then
          'Upload is complete, Save to DB here or whatever
     end if
    

    -1 is used on CHUNKS because chunks is -1 from the last chunk, if that makes sense.

    To get the file name all you need to add in your handler.ashx is..

    fileName = If(context.Request("name") IsNot Nothing, context.Request("name"), String.Empty)
    

    In order to get unique fileName from Pluplaod across to your handler, you need to tell Plupload(on the client) to use unique names.

    var uploader = new plupload.Uploader({
            runtimes: 'html5,flash,silverlight,html4',
            max_file_size: '20mb',
            url: '../handler.ashx',
            chunk_size: '100kb',
            unique_names: true,
            multipart_params: { imageType: $('#myDiv').attr("MyIMageType"), custom: 'This is static custom text' },
    

    In your handler you call the 'name' request again and you will have the unqie names that pluplaoder made.. also to request the data in the multipart you do as usual request

    PictureType = If(context.Request("imageType") IsNot Nothing, [Enum].Parse(GetType(PictureType), context.Request("imageType")), Nothing)
    
    
    Dim myCustom as String = If(context.Request("custom") IsNot Nothing, context.Request("custom"))
    

    In response to your SQL you need to encapsulate the file name withing ' otherwise spaces and special characters will break the SQLCommand, because SQL will think its another variable or command instead of treating it purely as a string. This is also a common problem for SQL Injection.. Allowing hackers to inject code because of code like this.