dxFileUploader

The dxFileUploader widget enables an end user to specify a file or several files to be uploaded to the server, and upload them synchronously or asynchronously. The widget is based on an input element with the type attribute set to "file".

View Demo

Watch Video

Enable Multiple Selection

By default, the widget enables an end user to select only a single file at a time. You can change the default behavior assigning true to the multiple option. This enables a user to select multiple files at once. In this case, you can access the collection of selected files using the values option.

JavaScript
var fileUploaderOptions = {
    multiple: true
}

Specify Accepted File Types

The widget also enables you to prevent an end user from uploading undesirable file types. Use the accept option to specify the file types accepted by the file selection dialog.

JavaScript
var fileUploaderOptions = {
    accept: "image/*"
}

The value of this option is passed to the accept attribute of the underlying input element. Thus, the option supports the same values as the attribute. Refer to input element documentation for information on available values.

Access Selected Files

You can obtain additional information on selected files. This information is represented by an object containing the following fields (not supported by Internet Explorer 8).

  • lastModifiedDate
    Specifies the date and time of the last selected file modification.

  • name
    Specifies the selected file name.

  • size
    Specifies the selected file size in bytes.

  • type
    Specifies the MIME type of the selected file.

NOTE
If your application is running on Internet Explorer 8, the info object includes only the name field, which contains the selected file name.

If the multiple mode is disabled, you can access file information using the value option, which holds the described object. Otherwise, the widget holds an array of such objects in the values option.

Uploading Files

For uploading files using the dxFileUploader widget, you should implement a service that saves uploaded files on a server. The service URL is passed to the action attribute of a web form or to the uploadUrl option of the widget depending on the upload mode you use. You should also specify the name option of the widget to access the uploaded files within a web server.

Asynchronous mode:

JavaScript
var fileUploaderOptions = {
    uploadMode: 'useButtons',
    name: 'myFile',
    uploadUrl: '/upload.php',
}

In synchronous mode, the widget should be enclosed in the form element.

HTML
<form action="/upload.php" method="post" enctype="multipart/form-data">
    <div id="fileUploader"></div>
    <input type="submit">
</form>
JavaScript
$("#fileUploader").dxFileUploader({
    name: 'myFile'
});
AngularJS Approach
HTML
<form action="/upload.php" method="post" enctype="multipart/form-data">
    <div dx-file-uploader={
        name: 'myFile'
    }"></div>
    <input type="submit">
</form>
Knockout Approach
HTML
<form action="/upload.php" method="post" enctype="multipart/form-data">
    <div data-bind="dxFileUploader: {
        name: 'myFile'
    }"></div>
    <input type="submit">
</form>

The dxFileUploader widget can upload files synchronously (using a web form) or asynchronously (using FormData and AJAX), depending on the selected upload mode. The upload mode is specified using the uploadMode option, which accepts the following values.

  • "instantly"
    Asynchronous upload. Starts uploading instantly as files are selected.

  • "useButtons"
    Asynchronous upload. Starts uploading when a user clicks the "Upload" button.

  • "useForm"
    Synchronous upload. Uploads the specified files when the Submit button of the current form is clicked.

NOTE
Internet Explorer 8 and 9 support only synchronous uploading because they do not support FormData.

The following example illustrates the dxFileUploader widget configured for the asynchronous upload. By default, the uploadMode option is set to 'instantly'.

JavaScript
var fileUploaderOptions = {
    selectButtonText: 'Select file',
    labelText: 'Drop file here',
    multiple: true,
    name: 'myFile',
    uploadMode: 'useButtons',
    uploadUrl: '/upload.php'
}

The example below demonstrates dxFileUploader in synchronous mode.

HTML
    <form action="/upload.php" method="post" enctype="multipart/form-data">
        <div id="fileUploader"></div>
        <input type="submit">
    </form>
JavaScript
$("#fileUploader").dxFileUploader({
    selectButtonText: 'Select file',
    labelText: 'Drop file here',
    multiple: true,
    name: 'myFile[]',
    uploadMode: 'useForm',
});
AngularJS Approach
HTML
<form action="/upload.php" method="post" enctype="multipart/form-data">
    <div dx-file-uploader={
        selectButtonText: 'Select file',
        labelText: 'Drop file here',
        multiple: true,
        name: 'myFile[]',
        uploadMode: 'useForm',
    }"></div>
    <input type="submit">
</form>
Knockout Approach
HTML
<form action="/upload.php" method="post" enctype="multipart/form-data">
    <div data-bind="dxFileUploader: {
        selectButtonText: 'Select file',
        labelText: 'Drop file here',
        multiple: true,
        name: 'myFile[]',
        uploadMode: 'useForm',
    }"></div>
    <input type="submit">
</form>
NOTE
In synchronous mode, if you enable multiple file selection, you should specify the name option, using "[]" (as demonstrated in the example above). This is essential for working not only with the last file, but with the whole set of uploaded files. If multiple file selection is disabled, square brackets are not required. In asynchronous mode, each file is uploaded using a separate AJAX request; that is why square brackets are also unnecessary in this case.

Since asynchronous mode uses AJAX requests, the current web page is not reloaded after upload is complete. In this case, the server informs the widget about upload results using the appropriate response code (for example, 400 or 500).

PHP

//Check to see if the array of uploaded files exists.
if (!isset($_FILES['myFile'])) {
    http_response_code(400);
}
NOTE
The PHP function httpresponsecode can be applied for PHP5 >= 5.4.0. In earlier versions, use the header function.

C#

//Check to see if the request holds a file and then make sure that the file is not empty.
if (myFile == null || myFile.ContentLength <= 0) 
{
    Response.StatusCode = 400;
    Response.StatusDescription = "File is not specified";
}

The synchronous upload implies that your application navigates to the URL specified in the action attribute. In this case, you can reload the initial page, or redirect to another page.

Server Side Implementation in ASP.NET

To create a file upload service on ASP.NET MVC, add a controller to the project, and create an action implementing the service logic.

public class UploadController: Controller
{
    public ActionResult Upload() {
        //Implement service logic here
    }
}

Use the HttpRequest.Files property to get the collection of files being uploaded. Each collection item is an instance of the HttpPostedFileBase class, which provides the following information.

  • ContentLength
    The size of an uploaded file, in bytes.

  • ContentType
    The MIME content type of a file sent by a client.

  • FileName
    The original name of the file on the client machine.

  • InputStream
    A Stream object that points to an uploaded file to prepare to read the file contents.

Both synchronous and asynchronous modes include common steps. First, check to ensure that the file size is greater than zero. Then, save the uploaded file to the specified directory.

if (myFile.ContentLength > 0) {
    ...
    myFile.SaveAs(pathToFile);
} else {
    // Handle error
}
NOTE
Check if the file is being saved to the required directory. This is necessary, because the path can be modified using special characters in the file name; for example, two consecutive dots or the tilde.

For server security, upload files of a specific type. To do this, use the ContentType property. The example below demonstrates how to upload only images.

if (myFile.ContentType.Contains("image")) {
    ...
} else {
    // Handle error
}
NOTE
Use additional checks to ensure that the client is not allowed to upload files with malicious content such as server scripts.

In addition, you may want to limit the file size; do this by checking the ContentLength property.

int maxFileSize = 1024*700;
if (myFile.ContentLength < maxFileSize) {
    ...
} else {
    // Handle error
}

Asynchronous Uploading

In asynchronous mode, each file is uploaded using a separate AJAX request.

The following example demonstrates the processing of the uploaded file in asynchronous mode.

C#

public ActionResult AsyncUpload()
{
    HttpPostedFileBase myFile = Request.Files["myFile"];

    //Specify the target location for saving uploaded files.
    string targetLocation = Server.MapPath("~/Files/");

    //Specify the maximum allowed size for uploaded files (700kb).
    int maxFileSize = 1024 * 700;

    //Check to see if the request holds a file and the file is not empty.
    if (myFile == null || myFile.ContentLength <= 0) {
        Response.StatusCode = 400;
        Response.StatusDescription = "File is not specified";
        return new EmptyResult();
    }

    //Check to see if the file size matches the allowed size.
    if (myFile.ContentLength > maxFileSize) {
        Response.StatusCode = 400;
        Response.StatusDescription = "File is too large";
        return new EmptyResult();
    }

    //Check to see if the file is an image.
    if (!myFile.ContentType.Contains("image")) {
        Response.StatusCode = 400;
        Response.StatusDescription = "Invalid type";
        return new EmptyResult();
    }

    try {
        string path = System.IO.Path.Combine(targetLocation, myFile.FileName);
        // Make sure that the file will be saved to the required directory.
        // Also ensure that the client can't upload files with malicious content.
        // If checks are passed, save the file.
            myFile.SaveAs(path);
    }
    catch (Exception e) {
        Response.StatusCode = 400;
        Response.StatusDescription = "Bad file name";
        return new EmptyResult();
    }
    return new EmptyResult();
}

VB

Function AsyncUpload() As ActionResult
    Dim myFile As HttpPostedFileBase = Request.Files("myFile")
    'Specify the target location for saving uploaded files.'
    Dim targetLocation As String = Server.MapPath("~/Files/")

    'Specify the maximum allowed size for uploaded files (700kb).'
    Dim maxFileSize As Integer = 1024 * 700

    'Check to see if the request holds a file and the file is not empty.'
    If (IsNothing(myFile) Or myFile.ContentLength <= 0) Then
        Response.StatusCode = 400
        Response.StatusDescription = "File is not specified"
        Return New EmptyResult()
    End If

    'Check to see if the file size matches the allowed size.'
    If (myFile.ContentLength > maxFileSize) Then
        Response.StatusCode = 400
        Response.StatusDescription = "File is not specified"
        Return New EmptyResult()
    End If

    'Check to see if the file is an image.'
    If (Not myFile.ContentType.Contains("image")) Then
        Response.StatusCode = 400
        Response.StatusDescription = "File is not specified"
        Return New EmptyResult()
    End If

    Try
        Dim path As String = System.IO.Path.Combine(targetLocation, myFile.FileName)
        ' It is required to check path to a file and make sure, that the file will be saved in the specified directory.'
        ' Also ensure that the client is not able to upload files with malicious content.'
        ' If checks are passed, save the file to the directory.'
            myFile.SaveAs(path)
    Catch ex As Exception
        Response.StatusCode = 400
        Response.StatusDescription = "Bad file name"
        Return New EmptyResult()
    End Try

    Return New EmptyResult()

End Function

If upload has failed, send the response with an error HTTP status code using the Response.StatusCode property. You can also set the HTTP status string using the Response.StatusDescription property (see the example above).

Synchronous Uploading

In the synchronous mode, several files may be passed in a single request.

The example below demonstrates the processing of the uploaded files in synchronous mode.

C#

public ActionResult SyncUpload() {

    //Specify the target location for saving uploaded files.
    string targetLocation = Server.MapPath("~/Files/");

    //Specify the maximum allowed size for uploaded files (700kb)
    int maxFileSize = 1024 * 700;

    //Check to see if the request holds files.
    if(Request.Files.Count == 0)
        return View("Index");

    HttpFileCollectionBase myFiles = Request.Files;
    for (int index = 0; index < myFiles.Count; index++ ) {
        HttpPostedFileBase myFile = myFiles[index];

        //Check to make sure that the file is not empty.
        if (myFile.ContentLength <= 0)
            continue;
        string fileName = myFile.FileName;

        //Check to see if the file size matches the allowed size.
        if (myFile.ContentLength > maxFileSize)
            continue;

        //Check to see if the file is an image.
        if (!myFile.ContentType.Contains("image"))
            continue;

        try {
            string path = System.IO.Path.Combine(targetLocation, myFile.FileName);
            // It is required to check path to a file and make sure, that the file will be saved to the required directory.
            // Also ensure that the client can't upload files with malicious content.
            // If checks are passed, save the file to the directory.
                myFile.SaveAs(path);
        }
        catch (Exception e) {
            continue;
        }
    }
    return View("Index");
}

VB

Function SyncUpload() As ActionResult
    'Specify the target location for saving uploaded files.'
    Dim targetLocation As String = Server.MapPath("~/Files/")

    'Specify the maximum allowed size for uploaded files (700kb).'
    Dim maxFileSize As Integer = 1024 * 700

    Dim myFiles As HttpFileCollectionBase = Request.Files

    'Check to see if the request holds files.'
    If myFiles.Count = 0 Then
        Return View("Index")
    End If

    For i = 0 To myFiles.Count - 1
        Dim myFile As HttpPostedFileBase = myFiles(i)

        'Check to make sure that the file is not empty'
        If (myFile.ContentLength <= 0) Then
            Continue For
        End If

        Dim fileName As String = myFile.FileName

        'Check to see if the file size matches the allowed size.'
        If (myFile.ContentLength > maxFileSize) Then
            Continue For
        End If

        'Check to see if the file is an image.'
        If (Not myFile.ContentType.Contains("image")) Then
            Continue For
        End If

        Try
            Dim path As String = System.IO.Path.Combine(targetLocation, myFile.FileName)
            'Make sure that the file will be saved to the required directory.'
            'Also ensure that the client is not able to upload files with malicious content.'
            'If checks are passed, save the file to the directory.'
                myFile.SaveAs(path)
        Catch ex As Exception
            Continue For
        End Try
    Next i

    Return View("Index")
End Function

Server Side Implementation in PHP

To access information about uploaded files, use the $_FILES associative array. It contains the following items.

  • $_FILES['myFile']['name']
    The original name of the file on the client machine.

  • $_FILES['myFile']['type']
    The MIME type of the file. For example: "image/gif".

  • $_FILES['myFile']['size']
    The size (in bytes) of the uploaded file.

  • $_FILES['myFile']['error']
    The error code associated with the file upload.

Here "myFile" is the value assigned to the name option of the dxFileUploader widget.

Both synchronous and asynchronous modes include several common steps. First, check if the $_FILES array exists. For this purpose, use the isset function.

<?php
    if(!isset($_FILES['myFile'])) {
        exit;
    }
?>

By default, an uploaded file is stored in a server's temporary directory under a temporary filename until the script finishes its work. Check if the file was successfully uploaded to the server.

<?php
    if (is_uploaded_file($_FILES['myFile']['tmp_name'])) {
        ...
    } else {
        // Handle error
    }
?>

For server security, check the type of the uploaded files. For this purpose, you can use the $_FILES['myFile']['type']. The following example demonstrates how to upload only images.

<?php
    if(strpos($_FILES['myFile']['type'], "image") !== false ) {
        ...
    } else {
        // Handle error
    }
?>
NOTE
Use additional checks to ensure that the client is not allowed to upload files with malicious content such as server scripts. Also, check if the file is being saved to the required directory. This is necessary, because the path can be modified using special characters in the file name; for example, two consecutive dots or the tilde.

In addition, you can limit the file size by checking $_FILES['myFile']['size'] data.

<?php
    $max_image_size = 700*1024;
    if ($_FILES['myFile']['size'] < $max_image_size ) {
        ...
    } else {
        // Handle error
    }
 ?>

Asynchronous Uploading

In asynchronous mode, each file is uploaded using a separate AJAX request.

The example below demonstrates the processing of the uploaded file in asynchronous mode.

<?php
    //Check to see if the array of uploaded files exists.
    if(!isset($_FILES['myFile'])) {
        http_response_code(400);
        exit;
    }

    //Specify the maximum allowed size for uploaded files (700kb).
    $max_image_size = 700*1024;

    //Check to see if the file was successfully uploaded to the server's temporary directory.
    if(!is_uploaded_file($_FILES['myFile']['tmp_name'])) {
        http_response_code(400);
        exit;
    }

    //Check to see if the file size matches the allowed size.
    if($_FILES['myFile']['size'] > $max_image_size) {
        http_response_code(400);
        exit;
    }

    //Check to make sure that the file is an image.
    if(strpos($_FILES['myFile']['type'], "image") === false) {
        http_response_code(400);
        exit;
    }

    //Specify the path to the file.
    $path_to_file = "images/".$_FILES['myFile']['name'];

    // Make sure that the file will be saved to the required directory.
    // Also ensure that the client can't upload files with malicious content.
    // If checks are passed, move the file to the directory.
        move_uploaded_file($_FILES['myFile']['tmp_name'], $path_to_file);
?>

If the upload has failed, send the response with an error HTTP status code using the PHP function httpresponsecode. It can be applied for PHP5 >= 5.4.0. In earlier versions use the header function.

Synchronous Uploading

In synchronous mode, several files may be passed in a single request. That is why we use $_FILES as an array of associative arrays.

The following example demonstrates the processing of uploaded files in synchronous mode.

<?php
    //Check if the array of uploaded files exists.
    if(!isset($_FILES['myFile'])) {
        exit;
    }

    //Specify the maximum allowed size for uploaded files (700kb).
    $max_image_size = 700*1024;

    foreach($_FILES['myFile']['name'] as $k=>$f) {
        //Check if the file was successfully uploaded to a server's temporary directory.
        if(!is_uploaded_file($_FILES['myFile']['tmp_name'][$k])) {
            continue;
        }

        //Check if the file size matches the allowed size.
        if($_FILES['myFile']['size'][$k] > $max_image_size ) {
            continue;
        }

        //Check to see if the file is an image.
        if(strpos($_FILES['myFile']['type'][$k], "image") === false) {
            continue;
        }

        //Specify the path to the file.
        $path_to_file = "images/".$_FILES['myFile']['name'][$k];

        // Make sure that the file will be saved to the required directory.
        // Also ensure that the client can't upload files with malicious content.
        // If checks are passed, move the file.
            move_uploaded_file($_FILES['myFile']['tmp_name'][$k], $path_to_file);
    }
    //Redirect to another page.
    header("Location: /index.php");
?>