Uploading Files to the Application Server

Description

Web publishing applications only. To upload a file, the <form> tag must use the POST method and set the enctype to multipart/form-data as follows:

<form method="POST" action="upload.a5w" enctype="multipart/form-data">

This enables the user's browser to correctly encode the data in the file so it can be sent across the Internet. The other component of the form is a field to specify what file to upload. This is done with an input field that has a type of file:

<input type="file" name="FileToUpload">

An input field with type "file" creates a text control with a Browse button used to open the file explorer and select a file on the computer.

When the form is submitted, the browser encodes the selected file and uploads it as part of the HTTP request sent to the server. The server decodes the file, making the file available in the A5W environment as an INET::UploadedFile object. The variable name of the INET::UploadedFile object is the value for the input field's name attribute. For example, if the name attribute for the input field is "FileToUpload", the variable name would be:

FileToUpload

If the uploaded file is large, using INET::UploadedFile data property is not recommended. When the data property is referenced, the file is loaded into memory. For very large files, this can potentially consume all of the virtual memory on the system and cause errors. Use either the SaveToFile or SaveToStorage methods for the INET::UploadedFile object to save the file without loading it into memory. The file's size can be checked using the INET::UploadedFile size property.

To enforce a restriction on what is uploaded, the user must upload the file first. Once the file is uploaded, the file can be validated. This is a limitation of HTML and not the Application Server.

If the file meets the upload criteria, the file can be saved to the server, uploaded to AmazonS3 or Azure storage, inserted it into a table, etc. If it does not meet the upload criteria, simply don't do anything with the uploaded data, and the file will be deleted from memory when the page finishes loading.

if (FileToUpload.size > 1000000) then
    Context.Response.Write("<p>File is too large</p>")
    end
end if

Uploading Files Using SaveToStorage

The following example shows how to implement file uploading to the Application Server using Storage containers. Place this code into a page named "fileupload.a5w". The uploaded file will be placed in the document root as defined on the General tab of the Application Server Control Panel.

<html>
    <head>
        <title>File Upload to Storage</title>
    </head>
    <body>
    <%a5
        if eval_valid("Request.Variables.singlefile")
            FileToUpload = Request.Variables.singlefile

            dim Filename as c = ""
            dim MimeType as c = ""
        
            dim Container as A5Storage::DataContainer = null_value()
            dim StorageConnString as c = "Provider='Disk';Timeout='10000';Container='c:\Temp\Uploads';"
            dim Result as CallResult
            Result = A5Storage::DataContainer::Open(Container, StorageConnString)
            if Result.Success
                if FileToUpload.SaveToStorage(Container, FileToUpload.Filename, FileToUpload.ContentType)
                    Context.Response.Write("<p>Uploaded file was saved to storage.</p>")
                else
                    Context.Response.Write("<p>Could not save uploaded file to storage.</p>")
                end if
            else
                Context.Response.Write("<p>Could not open storage: " + Result.Text + "</p>")
            end if
        end if
    %>
    <form action="<%a5?Context.Request.ScriptName%>" method="post" enctype="multipart/form-data">
        <input type="file" name="singlefile"/><br/>
        <input type="submit"/>
    </form>
    </body>
</html>

Uploading Files Using SaveToFile

The SaveToFile method can also be used to save the file. For example:

<html>
    <head>
        <title>File Upload Using SaveToFile</title>
    </head>
    <body>
    <%a5
        if eval_valid("Request.Variables.singlefile")
            FileToUpload = Request.Variables.singlefile

            dim Filepath as c = "C:\myapp\data\uploadedFiles\\"

            if FileToUpload.SaveToFile(Filepath + FileToUpload.Filename)
                Context.Response.Write("<p>Uploaded file was saved.</p>")
            else
                Context.Response.Write("<p>Could not save uploaded file.<br>Error reported:<br>"+FileToUpload.CallResult.Text+"</p>")
            end if

        end if
    %>
    <form action="<%a5?Context.Request.ScriptName%>" method="post" enctype="multipart/form-data">
        <input type="file" name="singlefile"/><br/>
        <input type="submit"/>
    </form>
    </body>
</html>
SaveToFile will fail if the destination folder does not exist.

Uploading Multiple Files

Multiple files can be uploaded from single HTML element by adding the multiple attribute to the input field. For example:

<input type="file" name="multifile[]" multiple="true">

The name of the input element must end with square brackets ("[]"). This indicates to Alpha Anywhere that multiple files may be uploaded.

The example below demonstrates how to upload multiple files:

<html>
    <head>
        <title>Uploading Multiple Files</title>
    </head>
    <body>
    <%a5
        if eval_valid("Request.Variables.multifile")
            FilesToUpload = Request.Variables.multifile

            dim Filepath as c = "C:\myapp\data\uploadedFiles\\"
            dim numFiles as n = FilesToUpload.size()

            ' FilesToUpload is an array of INET::UploadedFile objects
            ' iterate over all files and upload them individually:
            for i = 1 to numFiles
                currFile = FilesToUpload[i]
                if currFile.SaveToFile(Filepath + currFile.Filename)
                    Context.Response.Write("<p>File "+currFile.Filename+" was saved.</p>")
                else
                    Context.Response.Write("<p>Could not save file "+currFile.Filename+". <br>Error reported:<br>"+currFile.CallResult.Text+"</p>")
                end if
            next
        end if
    %>
    <form action="<%a5?Context.Request.ScriptName%>" method="post" enctype="multipart/form-data">
        <input type="file" name="multifile[]" multiple="true"/><br/>
        <input type="submit"/>
    </form>
    </body>
</html>

Limitations

Web Applications Only

See Also