Building a Classic ASP File Uploader
Tags: asp, dotnet, tutorial, development
Published: 2023-07-14 21:52:00

## Introduction:
Uploading files to a server is a common requirement in web development projects. In this blog, we will explore how to implement file uploads using Classic ASP, providing step-by-step guidance and examples. Classic ASP is a server-side scripting language that is still widely used, and understanding how to handle file uploads with it is essential for web developers working with legacy systems.

---

## Step 1: Setting up the project
Let’s setup the project first.

1. Create a new folder for storing the project files.

    ![Create a new folder](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6w5ab81i3n0j30q7bpmg.png)



2. Open the folder and create a new asp file. I have named the file as uploadhelper.asp.


    ![Create a new asp file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tl1vr7bbhbg4ku7fpch8.png)


3. Paste the below code into uploadhelper.asp. This code is going to help in uploading the file. I found this code while searching for ways to create the uploader. I had to make a lot of changes to this file to make it to work. Now, it’s working. I have set the upload limit to close to 50 MB in the first line of code.
    

    ```
<%
Const MAX_UPLOAD_SIZE        = 500000000 '50 MB
Const MSG_NO_DATA            = "Nothing to upload."
Const MSG_EXCEEDED_MAX_SIZE  = "You exceeded the maximum upload size."
Const MSG_BAD_REQUEST_METHOD = "Bad request method. Use the POST method."
Const MSG_BAD_ENCTYPE        = "Bad encoding type. Use a ""multipart/form-data"" enctype."
Const MSG_ZERO_LENGTH        = "Zero length request."

    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    ':::                                                                 :::
    ':::  The file was modified by Shekhar Tarare (shekhartarare.com)    :::
    ':::  on 20/06/2023. I have fixed issues with the file by making     :::
    ':::  some changes to the code. It's working as of now. Feel free to ::: 
    ':::  modify according to your needs.                                :::                                
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Class UploadHelper
    Private m_Request
    Private m_Files
    Private m_Error

    Public Property Get GetError
        GetError = m_Error
    End Property

    Public Property Get FileCount
        FileCount = m_Files.Count
    End Property

    Public Function File(index)
        If m_Files.Exists(index) Then
           Set File = m_Files(index)
        Else  
           Set File = Nothing
        End If
    End Function

    Public Default Property Get Item(strName)
        If m_Request.Exists(strName) Then
            Item = m_Request(strName)
        Else  
            Item = ""
        End If
    End Property

    Private Sub Class_Initialize
        Dim iBytesCount, strBinData

        'first of all, get amount of uploaded bytes:
        iBytesCount = Request.TotalBytes

        'abort if nothing there:
        If iBytesCount = 0 Then
            m_Error = MSG_NO_DATA
            Exit Sub
        End If

        'abort if exceeded maximum upload size:
        If iBytesCount > MAX_UPLOAD_SIZE Then
            m_Error = MSG_EXCEEDED_MAX_SIZE
            Exit Sub
        End If

        If Request.ServerVariables("REQUEST_METHOD") = "POST" Then 
            Dim CT, PosB, Boundary, PosE
            CT = Request.ServerVariables("HTTP_Content_Type")
            If LCase(Left(CT, 19)) = "multipart/form-data" Then
                PosB = InStr(LCase(CT), "boundary=") 
                If PosB > 0 Then Boundary = Mid(CT, PosB + 9) 
                PosB = InStr(LCase(CT), "boundary=") 
                If PosB > 0 Then 
                    PosB = InStr(Boundary, ",")
                    If PosB > 0 Then Boundary = Left(Boundary, PosB - 1)
                End If
                If iBytesCount > 0 And Boundary <> "" Then 
                    Boundary = "--" & Boundary
                    Dim Head, Binary
                    Binary = Request.BinaryRead(iBytesCount) 

                    'create private collections:
                    Set m_Request = Server.CreateObject("Scripting.Dictionary")
                    Set m_Files = Server.CreateObject("Scripting.Dictionary")

                    Call ParseRequest(Binary, Boundary)
                    Binary = Empty 
                Else
                    m_Error = MSG_ZERO_LENGTH
                    Exit Sub
                End If
            Else
                m_Error = MSG_BAD_ENCTYPE
                Exit Sub
            End If
        Else
            m_Error = MSG_BAD_REQUEST_METHOD
            Exit Sub
        End If
    End Sub

    Private Sub Class_Terminate
        Dim fileName
        If IsObject(m_Request) Then
            m_Request.RemoveAll
            Set m_Request = Nothing
        End If
        If IsObject(m_Files) Then
            For Each fileName In m_Files.Keys
                Set m_Files(fileName)=Nothing
            Next
            m_Files.RemoveAll
            Set m_Files = Nothing
        End If
    End Sub

    Private Sub ParseRequest(Binary, Boundary)
        Dim PosOpenBoundary, PosCloseBoundary, PosEndOfHeader, isLastBoundary
        Boundary = StringToBinary(Boundary)
        PosOpenBoundary = InStrB(Binary, Boundary)
        PosCloseBoundary = InStrB(PosOpenBoundary + LenB(Boundary), Binary, Boundary, 0)
        Dim HeaderContent, FieldContent, bFieldContent
        Dim Content_Disposition, FormFieldName, SourceFileName, Content_Type
        Dim TwoCharsAfterEndBoundary, n : n = 0
        Do While (PosOpenBoundary > 0 And PosCloseBoundary > 0 And Not isLastBoundary)
            PosEndOfHeader = InStrB(PosOpenBoundary + Len(Boundary), Binary, StringToBinary(vbCrLf + vbCrLf))
            HeaderContent = MidB(Binary, PosOpenBoundary + LenB(Boundary) + 2, PosEndOfHeader - PosOpenBoundary - LenB(Boundary) - 2)
            bFieldContent = MidB(Binary, (PosEndOfHeader + 4), PosCloseBoundary - (PosEndOfHeader + 4) - 2)
            GetHeadFields BinaryToString(HeaderContent), Content_Disposition, FormFieldName, SourceFileName, Content_Type
            Set objFileData = New FileData
            objFileData.FileName = SourceFileName
            objFileData.ContentType = Content_Type
            objFileData.Contents = bFieldContent
            objFileData.FormFieldName = FormFieldName
            objFileData.ContentDisposition = Content_Disposition
            Set m_Files(n) = objFileData
            Set objFileData = Nothing
            TwoCharsAfterEndBoundary = BinaryToString(MidB(Binary, PosCloseBoundary + LenB(Boundary), 2))
            isLastBoundary = TwoCharsAfterEndBoundary = "--"
            If Not isLastBoundary Then 
                PosOpenBoundary = PosCloseBoundary
                PosCloseBoundary = InStrB(PosOpenBoundary + LenB(Boundary), Binary, Boundary)
            End If
            n = n + 1
        Loop
    End Sub

    Private Function GetHeadFields(ByVal Head, Content_Disposition, Name, FileName, Content_Type)
        Content_Disposition = LTrim(SeparateField(Head, "content-disposition:", ";"))
        Name = (SeparateField(Head, "name=", ";")) 
        If Left(Name, 1) = """" Then Name = Mid(Name, 2, Len(Name) - 2)
        FileName = (SeparateField(Head, "filename=", ";")) 
        If Left(FileName, 1) = """" Then FileName = Mid(FileName, 2, Len(FileName) - 2)
        Content_Type = LTrim(SeparateField(Head, "content-type:", ";"))
    End Function

    Private Function SeparateField(From, ByVal sStart, ByVal sEnd)
        Dim PosB, PosE, sFrom
        sFrom = LCase(From)
        PosB = InStr(sFrom, sStart)
        If PosB > 0 Then
            PosB = PosB + Len(sStart)
            PosE = InStr(PosB, sFrom, sEnd)
            If PosE = 0 Then PosE = InStr(PosB, sFrom, vbCrLf)
            If PosE = 0 Then PosE = Len(sFrom) + 1
            SeparateField = Mid(From, PosB, PosE - PosB)
        Else
            SeparateField = Empty
        End If
    End Function

    Private Function BinaryToString(Binary)
        dim cl1, cl2, cl3, pl1, pl2, pl3
        Dim L
        cl1 = 1
        cl2 = 1
        cl3 = 1
        L = LenB(Binary)
        Do While cl1<=L
            pl3 = pl3 & Chr(AscB(MidB(Binary,cl1,1)))
            cl1 = cl1 + 1
            cl3 = cl3 + 1
            if cl3>300 then
                pl2 = pl2 & pl3
                pl3 = ""
                cl3 = 1
                cl2 = cl2 + 1
                if cl2>200 then
                    pl1 = pl1 & pl2
                    pl2 = ""
                    cl2 = 1
                End If
            End If
        Loop
        BinaryToString = pl1 & pl2 & pl3
    End Function

    Private Function StringToBinary(String)
        Dim I, B
        For I=1 to len(String)
            B = B & ChrB(Asc(Mid(String,I,1)))
        Next
        StringToBinary = B
    End Function
End Class
Class FileData
    Private m_fileName
    Private m_contentType
    Private m_BinaryContents
    Private m_AsciiContents
    Private m_imageWidth
    Private m_imageHeight
    Private m_checkImage
    Private m_formFieldName
    Private m_contentDisposition

    Public Property Get FormFieldName
        FormFieldName = m_formFieldName
    End Property

    Public Property Let FormFieldName(sFieldName)
        m_formFieldName = sFieldName
    End Property

    Public Property Get ContentDisposition
        ContentDisposition = m_contentDisposition
    End Property

    Public Property Let ContentDisposition(sContentDisposition)
        m_contentDisposition = sContentDisposition
    End Property

    Public Property Get FileName
        FileName = m_fileName
    End Property

    Public Property Get ContentType
        ContentType = m_contentType
    End Property

    Public Property Get ImageWidth
        If m_checkImage=False Then Call CheckImageDimensions
        ImageWidth = m_imageWidth
    End Property

    Public Property Get ImageHeight
        If m_checkImage=False Then Call CheckImageDimensions
        ImageHeight = m_imageHeight
    End Property

    Public Property Let FileName(ByVal strName)
        strName = Replace(strName, "/", "\")
        Dim arrTemp : arrTemp = Split(strName, "\")
        m_fileName = arrTemp(UBound(arrTemp))
    End Property

    Public Property Let CheckImage(blnCheck)
        m_checkImage = blnCheck
    End Property

    Public Property Let ContentType(strType)
        m_contentType = strType
    End Property

    Public Property Let Contents(strData)
        m_BinaryContents = strData
        m_AsciiContents = RSBinaryToString(m_BinaryContents)
    End Property

    Public Property Get Size
        Size = LenB(m_BinaryContents)
    End Property

    Private Sub CheckImageDimensions
        Dim width, height, colors
        Dim strType

        '''If gfxSpex(BinaryToAscii(m_BinaryContents), width, height, colors, strType) = true then
        If gfxSpex(m_AsciiContents, width, height, colors, strType) = true then
            m_imageWidth = width
            m_imageHeight = height
        End If
        m_checkImage = True
    End Sub

    Private Sub Class_Initialize
        m_imageWidth = -1
        m_imageHeight = -1
        m_checkImage = False
    End Sub

    Public Sub SaveToDisk(strFolderPath, ByRef strNewFileName)
        Dim strPath, objFSO, objFile
        Dim i, time1, time2
        Dim objStream, strExtension

        strPath = strFolderPath&"\"
        If Len(strNewFileName)=0 Then
            strPath = strPath & m_fileName
        Else  
            strExtension = GetExtension(strNewFileName)
            If Len(strExtension)=0 Then
                strNewFileName = strNewFileName & "." & GetExtension(m_fileName)
            End If
            strPath = strPath & strNewFileName
        End If

        time1 = CDbl(Timer)

        Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
        Set objFile = objFSO.CreateTextFile(strPath)

        objFile.Write(m_AsciiContents)

        '''For i=1 to LenB(m_BinaryContents)
        '''    objFile.Write chr(AscB(MidB(m_BinaryContents, i, 1)))
        '''Next          

        time2 = CDbl(Timer)

        objFile.Close
        Set objFile=Nothing
        Set objFSO=Nothing
    End Sub

    Private Function GetExtension(strPath)
        Dim arrTemp
        arrTemp = Split(strPath, ".")
        GetExtension = ""
        If UBound(arrTemp)>0 Then
            GetExtension = arrTemp(UBound(arrTemp))
        End If
    End Function

    Private Function RSBinaryToString(xBinary)
        'Antonin Foller, http://www.motobit.com
        'RSBinaryToString converts binary data (VT_UI1 | VT_ARRAY Or MultiByte string)
        'to a string (BSTR) using ADO recordset

        Dim Binary
        'MultiByte data must be converted To VT_UI1 | VT_ARRAY first.
        If vartype(xBinary)=8 Then Binary = MultiByteToBinary(xBinary) Else Binary = xBinary

        Dim RS, LBinary
        Const adLongVarChar = 201
        Set RS = CreateObject("ADODB.Recordset")
        LBinary = LenB(Binary)

        If LBinary>0 Then
            RS.Fields.Append "mBinary", adLongVarChar, LBinary
            RS.Open
            RS.AddNew
            RS("mBinary").AppendChunk Binary 
            RS.Update
            RSBinaryToString = RS("mBinary")
        Else  
            RSBinaryToString = ""
        End If
    End Function

    Function MultiByteToBinary(MultiByte)
        '© 2000 Antonin Foller, http://www.motobit.com
        ' MultiByteToBinary converts multibyte string To real binary data (VT_UI1 | VT_ARRAY)
        ' Using recordset
        Dim RS, LMultiByte, Binary
        Const adLongVarBinary = 205
        Set RS = CreateObject("ADODB.Recordset")
        LMultiByte = LenB(MultiByte)
        If LMultiByte>0 Then
            RS.Fields.Append "mBinary", adLongVarBinary, LMultiByte
            RS.Open
            RS.AddNew
            RS("mBinary").AppendChunk MultiByte & ChrB(0)
            RS.Update
            Binary = RS("mBinary").GetChunk(LMultiByte)
        End If
        MultiByteToBinary = Binary
    End Function

    Private Function BinaryToAscii(strBinary)
        Dim i, result
        result = ""
        For i=1 to LenB(strBinary)
            result = result & chr(AscB(MidB(strBinary, i, 1))) 
        Next
        BinaryToAscii = result
    End Function

    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    ':::                                                             :::
    ':::  This routine will attempt to identify any filespec passed  :::
    ':::  as a graphic file (regardless of the extension). This will :::
    ':::  work with BMP, GIF, JPG and PNG files.                     :::
    ':::                                                             :::
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    ':::          Based on ideas presented by David Crowell          :::
    ':::                   (credit where due)                        :::
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    '::: blah blah blah blah blah blah blah blah blah blah blah blah :::
    '::: blah blah blah blah blah blah blah blah blah blah blah blah :::
    '::: blah blah     Copyright *c* MM,  Mike Shaffer     blah blah :::
    '::: bh blah      ALL RIGHTS RESERVED WORLDWIDE      blah blah :::
    '::: blah blah  Permission is granted to use this code blah blah :::
    '::: blah blah   in your projects, as long as this     blah blah :::
    '::: blah blah      copyright notice is included       blah blah :::
    '::: blah blah blah blah blah blah blah blah blah blah blah blah :::
    '::: blah blah blah blah blah blah blah blah blah blah blah blah :::
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    ':::                                                             :::
    ':::  This function gets a specified number of bytes from any    :::
    ':::  file, starting at the offset (base 1)                      :::
    ':::                                                             :::
    ':::  Passed:                                                    :::
    ':::       flnm        => Filespec of file to read               :::
    ':::       offset      => Offset at which to start reading       :::
    ':::       bytes       => How many bytes to read                 :::
    ':::                                                             :::
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    Private Function GetBytes(flnm, offset, bytes)
        Dim startPos
        If offset=0 Then
            startPos = 1
        Else  
            startPos = offset
        End If
        if bytes = -1 then        ' Get All!
            GetBytes = flnm
        else
            GetBytes = Mid(flnm, startPos, bytes)
        end if
'        Dim objFSO
'        Dim objFTemp
'        Dim objTextStream
'        Dim lngSize
'        
'        Set objFSO = CreateObject("Scripting.FileSystemObject")
'        
'        ' First, we get the filesize
'        Set objFTemp = objFSO.GetFile(flnm)
'        lngSize = objFTemp.Size
'        set objFTemp = nothing
'        
'        fsoForReading = 1
'        Set objTextStream = objFSO.OpenTextFile(flnm, fsoForReading)
'        
'        if offset > 0 then
'            strBuff = objTextStream.Read(offset - 1)
'        end if
'        
'        if bytes = -1 then        ' Get All!
'            GetBytes = objTextStream.Read(lngSize)  'ReadAll
'        else
'            GetBytes = objTextStream.Read(bytes)
'        end if
'        
'        objTextStream.Close
'        set objTextStream = nothing
'        set objFSO = nothing
    End Function

    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    ':::                                                             :::
    ':::  Functions to convert two bytes to a numeric value (long)   :::
    ':::  (both little-endian and big-endian)                        :::
    ':::                                                             :::
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    Private Function lngConvert(strTemp)
        lngConvert = clng(asc(left(strTemp, 1)) + ((asc(right(strTemp, 1)) * 256)))
    end function

    Private Function lngConvert2(strTemp)
        lngConvert2 = clng(asc(right(strTemp, 1)) + ((asc(left(strTemp, 1)) * 256)))
    end function

    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    ':::                                                             :::
    ':::  This function does most of the real work. It will attempt  :::
    ':::  to read any file, regardless of the extension, and will    :::
    ':::  identify if it is a graphical image.                       :::
    ':::                                                             :::
    ':::  Passed:                                                    :::
    ':::       flnm        => Filespec of file to read               :::
    ':::       width       => width of image                         :::
    ':::       height      => height of image                        :::
    ':::       depth       => color depth (in number of colors)      :::
    ':::       strImageType=> type of image (e.g. GIF, BMP, etc.)    :::
    ':::                                                             :::
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    function gfxSpex(flnm, width, height, depth, strImageType)
        dim strPNG 
        dim strGIF
        dim strBMP
        dim strType
        dim strBuff
        dim lngSize
        dim flgFound
        dim strTarget
        dim lngPos
        dim ExitLoop
        dim lngMarkerSize

        strType = ""
        strImageType = "(unknown)"

        gfxSpex = False

        strPNG = chr(137) & chr(80) & chr(78)
        strGIF = "GIF"
        strBMP = chr(66) & chr(77)

        strType = GetBytes(flnm, 0, 3)

        if strType = strGIF then                ' is GIF
            strImageType = "GIF"
            Width = lngConvert(GetBytes(flnm, 7, 2))
            Height = lngConvert(GetBytes(flnm, 9, 2))
            Depth = 2 ^ ((asc(GetBytes(flnm, 11, 1)) and 7) + 1)
            gfxSpex = True
        elseif left(strType, 2) = strBMP then        ' is BMP
            strImageType = "BMP"
            Width = lngConvert(GetBytes(flnm, 19, 2))
            Height = lngConvert(GetBytes(flnm, 23, 2))
            Depth = 2 ^ (asc(GetBytes(flnm, 29, 1)))
            gfxSpex = True
        elseif strType = strPNG then            ' Is PNG
            strImageType = "PNG"
            Width = lngConvert2(GetBytes(flnm, 19, 2))
            Height = lngConvert2(GetBytes(flnm, 23, 2))
            Depth = getBytes(flnm, 25, 2)
            select case asc(right(Depth,1))
                case 0
                    Depth = 2 ^ (asc(left(Depth, 1)))
                    gfxSpex = True
                case 2
                    Depth = 2 ^ (asc(left(Depth, 1)) * 3)
                    gfxSpex = True
                case 3
                    Depth = 2 ^ (asc(left(Depth, 1)))  '8
                    gfxSpex = True
                case 4
                    Depth = 2 ^ (asc(left(Depth, 1)) * 2)
                    gfxSpex = True
                case 6
                    Depth = 2 ^ (asc(left(Depth, 1)) * 4)
                    gfxSpex = True
                case else
                    Depth = -1
            end select
        else
            strBuff = GetBytes(flnm, 0, -1)        ' Get all bytes from file
            lngSize = len(strBuff)
            flgFound = 0

            strTarget = chr(255) & chr(216) & chr(255)
            flgFound = instr(strBuff, strTarget)

            if flgFound = 0 then
                exit function
            end if

            strImageType = "JPG"
            lngPos = flgFound + 2
            ExitLoop = false

            do while ExitLoop = False and lngPos < lngSize
                do while asc(mid(strBuff, lngPos, 1)) = 255 and lngPos < lngSize
                    lngPos = lngPos + 1
                loop

                if asc(mid(strBuff, lngPos, 1)) < 192 or asc(mid(strBuff, lngPos, 1)) > 195 then
                    lngMarkerSize = lngConvert2(mid(strBuff, lngPos + 1, 2))
                    lngPos = lngPos + lngMarkerSize  + 1
                else
                    ExitLoop = True
                end if
            loop

            if ExitLoop = False then
                Width = -1
                Height = -1
                Depth = -1
            else
                Height = lngConvert2(mid(strBuff, lngPos + 4, 2))
                Width = lngConvert2(mid(strBuff, lngPos + 6, 2))
                Depth = 2 ^ (asc(mid(strBuff, lngPos + 8, 1)) * 8)
                gfxSpex = True
            end if
        end if
    End Function
End Class
%>
    ```
4. We need to create a form, which will be having the file selector and a button to upload the selected files. Create a new asp file, let’s call it as uploadhelpertest.asp.

    ![Create one more asp file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lqyxvpwz5pnta1cqptmf.png)



5. Paste the below code into uploadhelperTest.asp.
    

    ```
<!-- #include file="uploadhelper.asp" -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title></title>
  </head>
  <body>
    <form action="<%=Request.ServerVariables("SCRIPT_NAME")%>?cmd=upload" method="POST" enctype="multipart/form-data">
      File: <input type="file" name="files[]" multiple>
      <input type="submit" value="Upload">
    </form> 
<%
If Request("cmd")="upload" Then
    Dim objUpload : Set objUpload = New UploadHelper
    If objUpload.GetError <> "" Then
        Response.Write("Warning: "&objUpload.GetError)
    Else  
        Response.Write("found "&objUpload.FileCount&" files...<br />")
        Dim x : For x = 0 To objUpload.FileCount - 1
            Response.Write("file name: "&objUpload.File(x).FileName&"<br />")
            Response.Write("file type: "&objUpload.File(x).ContentType&"<br />")
            Response.Write("file size: "&objUpload.File(x).Size&"<br />")
            Response.Write("Saved at: D:\TestASPProject\Photos<br />")
            'If want to convert the virtual path to physical path then use MapPath
            'Call objUpload.File(x).SaveToDisk(Server.MapPath("/public"), "")
            Call objUpload.File(x).SaveToDisk("D:\TestASPProject\Photos", "")
            Response.Write("file saved successfully!")
            Response.Write("<hr />")
        Next            
    End If
End If
%>
  </body>
</html>
    ```

    > **Explanation of the above code:**
    > We are including the uploadhelper.asp first.
    > We have a created a form with post action. It’s having an input of type file and a button of type submit.
    > At the end, we are having server code. It’s looping over submitted file, It’s printing the details of the file and saving the file one by one to the folder “D:\TestASPProject\Photos”.

6. As we are trying to saving the files to the folder “D:\TestASPProject\Photos”. We need to make sure that the folder is present on the path else it will throw the error. Let’s create a new folder called Photos.

    ![Create a folder](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bpl4wc4uj1208oovta7l.png)

---

## Step 2: Publishing the project to IIS
1. If you don’t have IIS installed in your machine. Please follow the tutorial [here](https://shekhartarare.com/Archive/2023/6/a_step_by_step_guide_to_setting_up_iis_in_windows), I have already written a blog to setup IIS.

2. Let’s setup our project in IIS. Open Internet Information Services (IIS) Manager.

    ![Setup project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b0ug47g33psqv6eb7leh.png)



3. Expand the directory. Right click Sites and select Add Website…


    ![Add websites](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l70axzi7a0ezun4ijx98.png)


4. Enter the Site name. Select the project folder in Physical path input and set the bindings. I have selected the port 8080. Click OK to finish the setup.


    ![Enter details](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hxlzsfbt1m5vutt0k3hx.png)

---

## Step 3: Enable Directory Browsing
1. We have successfully published the site. We just need to perform few configuration. Click on the website and under IIS, click on Directory Browsing. If it is not showing under IIS, then you might have not selected this while setting up the IIS.

    ![Directory browsing](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b0ereikl7hiraw3q0dwi.png)



2. Click on the Open Feature button on the right side.

    ![Open feature](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o09b80yx6pmy77kulf1v.png)



3. Click on the Enable button to enable the directory browsing.

    ![Enable it](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/in4kc06fdwwzl6jku3bv.png)



4. Now we can browse the files after running the project.

    ![setup done](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wmg0p94but145ygnl15j.png)



5. After enabling the Directory Browsing. A web.config file will be added to our project folder.

    ![Check WebConfig](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rqo6lhhi4o6oyik2evwy.png)



6. It will store the settings. When opening the file, it is having the below content.


    ![open webconfig](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v5d5p3wspllwd3t92emw.png)


7. You will get the below screen when running the website.

    ![output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ebmkylcrk9zj158m9v0d.png)

---


## Step 4: Setup Upload Limit
In the uploadhelper.asp file, we have already setup the upload limit to close to 50 MB. But, that’s not enough, we need to setup the upload limit on IIS also to allow the operation. Otherwise, you will get many errors. Let’s setup those:

1. Click on website and select ASP. Click on Open Feature.


    ![ASP feature](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4p67rza3roweq0i1bby1.png)


2. Expand Limits Properties. Set Maximum Requesting Entity Body Limit to 500000000 and click on Apply to save the settings.

    ![Setup limit](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kcodxyjclvdwsti2fn35.png)



3. We need to setup one more thing. Click your website and select the Request Filtering. Click on Open Feature.

    ![Request filtering](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8duieado7ddbm627jwog.png)



4. Click on Edit Feature Settings…

    ![Edit feature](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wzit5p9nqsxeibyj1fr2.png)



5. Update the Maximum allowed content length (Bytes) to 500000000 and click OK to save the setting.


    ![Max allowed content length](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/og04jk7puuhwzmbv9uk1.png)


6. It will update the web.config.


    ![it will update webconfig](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f4xged5qp4wc7bo11ms7.png)

---

## Step 5: Testing the website
1. Click on Browse to open the website.

    ![Browse site](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t2m53s73sq7eckdq677d.png)



2. Click on uploadhelperTest.asp.


    ![Click on uploadhelper file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xtrvm0c09c2o68yn3mkw.png)


3. It will show the below screen.

    ![Output from file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pyposk6psi5hfl9ht28y.png)



4. Click on Choose Files. I am selecting 16 files having total of 38 MB.

   ![Click choose files](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q7pcytsk2tjj1kozpjer.png)



5. Click on Upload. It has printed the file details and showing the message as five saved successfully!


    ![Click upload](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z6bfyzfz86g0icwe6dj4.png)


6. Let’s check on our Photos folder. All the uploaded photos have been saved to this folder.

    ![Added to folder](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ssw7xqrwx0z9fnlxecs.png)



**Note:**If you want to modify the upload limit, then first make the change on the uploadhelper.asp file. In the first line, there is constant called MAX_UPLOAD_SIZE. Set that with whatever limit you want to set. Then, set the Maximum Requesting Entity Body Limit of the ASP Feature and Maximum allowed content length of the Request Filtering to the exact same limit.

---


> Project Code is available [here](https://github.com/ShekharTarare/File-Uploader-Using-Classic-ASP).

---

## Conclusion:
Handling file uploads in Classic ASP is essential for developers working with legacy systems. In this blog, we learned how to implement a file uploader using Classic ASP, following a step-by-step approach. By setting up the environment, creating an HTML form, and writing server-side code, we were able to successfully handle file uploads and store them on the server. Remember to adjust the file upload folder and permissions as needed in your specific scenario.

File uploads are a critical feature in many web applications, and understanding how to implement them using Classic ASP allows you to work effectively with existing systems. With this knowledge, you can enhance user experiences by enabling seamless file transfers between clients and servers.