ASP Code

How to Upload Files With ASP

This code will enable you to create the necessary object and functions in your ASP code to upload files from a form. You don't need to purchase, install, or configure any 3rd party components, you can just copy this code straight into your application to enable client file uploading!

Make sure you have the proper permissions set on the web server. The folder that you specify as the upload folder should have 'write' permissions allowed for authenticated users, or even 'everyone' if you're OK with that.

<%
Server.ScriptTimeout = 600000
session.Timeout = 300


Class FileUploader
    Public  Files
    Private mcolFormElem

    Private Sub Class_Initialize()
        Set Files = Server.CreateObject ("Scripting.Dictionary")
        Set mcolFormElem = Server.CreateObject("Scripting.Dictionary")
    End Sub
   
    Private Sub Class_Terminate()
        If IsObject(Files) Then
            Files.RemoveAll()
            Set Files = Nothing
        End If
        If IsObject(mcolFormElem) Then
            mcolFormElem.RemoveAll()
            Set mcolFormElem = Nothing
        End If
    End Sub

    Public Property Get Form(sIndex)
        Form = ""
        If mcolFormElem.Exists(LCase(sIndex)) Then Form = mcolFormElem.Item(LCase(sIndex))
    End Property

    Public Default Sub Upload()
        Dim biData, sInputName
        Dim nPosBegin, nPosEnd, nPos, vDataBounds, nDataBoundPos
        Dim nPosFile, nPosBound

        biData = Request.BinaryRead(Request.TotalBytes)
        nPosBegin = 1
        nPosEnd = InstrB(nPosBegin, biData, CByteString(Chr(13)))
       
        If (nPosEnd-nPosBegin) <= 0 Then Exit Sub
         
        vDataBounds = MidB(biData, nPosBegin, nPosEnd-nPosBegin)
        nDataBoundPos = InstrB(1, biData, vDataBounds)
       
        Do Until nDataBoundPos = InstrB(biData, vDataBounds & CByteString("--"))
           
            nPos = InstrB(nDataBoundPos, biData, CByteString("Content-Disposition"))
            nPos = InstrB(nPos, biData, CByteString("name="))
            nPosBegin = nPos + 6
            nPosEnd = InstrB(nPosBegin, biData, CByteString(Chr(34)))
            sInputName = CWideString(MidB(biData, nPosBegin, nPosEnd-nPosBegin))
            nPosFile = InstrB(nDataBoundPos, biData, CByteString("filename="))
            nPosBound = InstrB(nPosEnd, biData, vDataBounds)
           
            If nPosFile <> 0 And  nPosFile < nPosBound Then
                Dim oUploadFile, sFileName
                Set oUploadFile = New UploadedFile
               
                nPosBegin = nPosFile + 10
                nPosEnd =  InstrB(nPosBegin, biData, CByteString(Chr(34)))
                sFileName = CWideString(MidB(biData, nPosBegin, nPosEnd-nPosBegin))
                oUploadFile.FileName = Right(sFileName, Len(sFileName)-InStrRev(sFileName, "\"))

                nPos = InstrB(nPosEnd, biData, CByteString("Content-Type:"))
                nPosBegin = nPos + 14
                nPosEnd = InstrB(nPosBegin, biData, CByteString(Chr(13)))
               
                oUploadFile.ContentType = CWideString(MidB(biData, nPosBegin, nPosEnd-nPosBegin))
               
                nPosBegin = nPosEnd+4
                nPosEnd = InstrB(nPosBegin, biData, vDataBounds) - 2
                oUploadFile.FileData = MidB(biData, nPosBegin, nPosEnd-nPosBegin)
               
                If oUploadFile.FileSize > 0 Then Files.Add LCase(sInputName), oUploadFile
            Else
                nPos = InstrB(nPos, biData, CByteString(Chr(13)))
                nPosBegin = nPos + 4
                nPosEnd = InstrB(nPosBegin, biData, vDataBounds) - 2
                If Not mcolFormElem.Exists(LCase(sInputName)) Then mcolFormElem.Add LCase(sInputName), CWideString(MidB(biData, nPosBegin, nPosEnd-nPosBegin))
            End If

            nDataBoundPos = InstrB(nDataBoundPos + LenB(vDataBounds), biData, vDataBounds)
        Loop
    End Sub

    'String to byte string conversion
    Private Function CByteString(sString)
        Dim nIndex
        For nIndex = 1 to Len(sString)
           CByteString = CByteString & ChrB(AscB(Mid(sString,nIndex,1)))
        Next
    End Function

    'Byte string to string conversion
    Private Function CWideString(bsString)
        Dim nIndex
        CWideString =""
        For nIndex = 1 to LenB(bsString)
           CWideString = CWideString & Chr(AscB(MidB(bsString,nIndex,1)))
        Next
    End Function
End Class

Class UploadedFile
    Public ContentType
    Public FileName
    Public FileData
   
    Public Property Get FileSize()
        FileSize = LenB(FileData)
    End Property

    Public Sub SaveToDisk(sPath)
        Dim oFS, oFile
        Dim nIndex
   
        If sPath = "" Or FileName = "" Then Exit Sub
        If Mid(sPath, Len(sPath)) <> "\" Then sPath = sPath & "\"
   
        Set oFS = Server.CreateObject("Scripting.FileSystemObject")
        If Not oFS.FolderExists(sPath) Then Exit Sub
       
        Set oFile = oFS.CreateTextFile(sPath & FileName, True)
       
        For nIndex = 1 to LenB(FileData)
            oFile.Write Chr(AscB(MidB(FileData,nIndex,1)))
        Next

        oFile.Close
    End Sub
   
    Public Sub SaveToDatabase(ByRef oField)
        If LenB(FileData) = 0 Then Exit Sub
       
        If IsObject(oField) Then
            oField.AppendChunk FileData
        End If
    End Sub

End Class


Dim Uploader, File, savepath
' Create the FileUploader
Set Uploader = New FileUploader

' This starts the upload process
Uploader.Upload()


' Check if any files were uploaded
If Uploader.Files.Count = 0 Then
    Response.Write "File(s) not uploaded."
Else
    ' Loop through the uploaded files
    For Each File In Uploader.Files.Items
        ' Check where the user wants to save the file
        dim fullpath, fullpath1, headertext1, sql5, headertext2, headertext3
        ' Save the file
        savepath=Server.MapPath("/WSS1/files/")
        File.SaveToDisk savepath
        Response.Write "File Uploaded: " & File.FileName & "<br>"
        Response.Write "Size: " & File.FileSize & " bytes<br>"
        Response.Write "Type: " & File.ContentType & "<br><br>"
    Next
End If
%>

And here's the code for the HTML form:


<form method="post" enctype="multipart/form-data" action="upload.asp">
    Select a file to upload: <input type="file" size="40" name="FILE1" /> <input type="submit" value="Upload!" />
</form>
Share

11 Comments

  1. This code does not work, Error message:

    Microsoft VBScript runtime error '800a0005'

    Invalid procedure call or argument: 'InstrB'

    /upload.asp, line 47

  2. Hey great site, I've ran into a couple nice code bits here, but u really need to change your stylesheet to put a dark background on your code blocks. The white bg with white text…. yea, it's unreadable unless I highlight the text. Usability wise, it's reaaally annoying.

  3. that's great feedback. I'll have to look at the CSS for the plugin, see if I can fix it

  4. Hi Justin
    I have just come across that Invalid procedure call or argument: 'InstrB' using another file uploader similar to yours. It occurs in IE but not firefox.
    Any resolutions or workarounds?
    Thanks
    Kman

  5. I really can't explain that. It doesn't make sense that it would occur differently by browser, because it's a server-side script

  6. Hi Justin,
    Please put to lines to upload to a Database. It filename,size,type and file data

  7. Hi Justin,
    Your site is great – thanks for posting the very handy tips and techniques for ASP and PHP!
    I would like to see a code/tutorial for submitting multiple files in Classic ASP and another tutorial for performing multiple updates (when using sets of radio buttons in each row), as it seems like neither of these topics are covered anywhere I've been able to find.

    Many thanks and all the best,
    Louis

  8. Hi

    did anyone fix the probelm with the error with InstrB?

  9. The script in this article has bugs, that's why it bombs (e.g., the one-based InStrB function is passed zero for start position).

    If you're trying to do multi-file uploads or must use a FORM, then keep looking — I could't find a good free and script-only solution. But as long as you're just doing one file at a time using XHR, then this works great:

    0 Then
    Dim filename: filename = Unescape(Request.QueryString("filename"))
    Dim tmpdir: tmpdir= "D:\tmp\" 'or whatever
    Dim buf: buf = Request.BinaryRead(Request.TotalBytes)
    Dim fso: Set fso = Server.CreateObject("Scripting.FileSystemObject")
    Dim fd: Set fd = fso.CreateTextFile(fso.BuildPath(tmpdir, filename))
    Dim i
    For i = 1 to LenB(buf)
    fd.Write Chr(AscB(MidB(buf, i, 1)))
    Next
    fd.Close
    End if
    'do response (success, error, etc.) for your requirements…
    %>

  10. Ok, that code got really mangled, trying again…

    <%
    If Request.TotalBytes > 0 Then
    Dim filename: filename = Unescape(Request.QueryString("filename"))
    Dim tmpdir: tmpdir= "D:\tmp\" 'or whatever
    Dim buf: buf = Request.BinaryRead(Request.TotalBytes)
    Dim fso: Set fso = Server.CreateObject("Scripting.FileSystemObject")
    Dim fd: Set fd = fso.CreateTextFile(fso.BuildPath(tmpdir, filename))
    Dim i
    For i = 1 to LenB(buf)
    fd.Write Chr(AscB(MidB(buf, i, 1)))
    Next
    fd.Close
    End if
    'do response (success, error, etc.) for your requirements…
    %>

  11. The above works but is really really slow — anything that deals char by char is bound to be. Then I found ADODB.Stream…

    The following is the final solution I used, and it's blazingly fast:

    Dim filename: filename = Unescape(Request.QueryString("filename"))
    Dim tmpdir: tmpdir= "D:\tmp\" 'or whatever
    Dim data: data = Request.BinaryRead(Request.TotalBytes)
    Dim fso: Set fso = Server.CreateObject("Scripting.FileSystemObject")
    Dim stream: Set stream = CreateObject("ADODB.Stream")
    stream.Type = 1 'adTypeBinary
    stream.Open
    stream.Write data
    stream.SaveToFile fso.BuildPath(uploaddir, filename), 2 'adSaveCreateOverWrite

Leave a Reply

Your email address will not be published. Required fields are marked *

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Anti-spam image