Blazor Upload Overview

The Blazor Upload component lets users upload files to a server endpoint asynchronously. Users can select one or multiple files. The upload process can start immediately after selection or after a button click. Users can also delete their uploaded files. The component can validate the selected files' extensions and size.

Telerik UI for Blazor Ninja image

The Upload component is part of Telerik UI for Blazor, a professional grade UI library with 100+ native components for building modern and feature-rich applications. To try it out sign up for a free 30-day trial.

Upload vs. FileSelect

The FileSelect and Upload components are similar and even inter-changeable. The major difference is how they communicate with the server and this can determine which component to use.

  • The FileSelect is more suitable for WebAssembly apps if you want to receive and manipulate the file in the browser's .NET runtime. Uploading the file to a remote server is optional and depends on manual coding in the OnSelect handler. The benefit is that FileSelect allows full control over the upload process. In Blazor Server apps, the FileSelect uses the SignalR WebSocket and large file support (> 32KB) requires MaximumReceiveMessageSize configuration.
  • The Upload uses the HTTP protocol. Prefer this component in Blazor Server and WebAssembly apps to directly send files to a remote endpoint, as HTTP is the usual way to do this. Large file support requires different configurations, depending on the receiving web server.

Creating Blazor Upload

There are two main steps to use the Upload component:

Afterwards, take care of application security and check our tips for large file uploads and CORS.

Configure the Component

  1. Add the TelerikUpload tag.
  2. Set SaveUrl to the endpoint URL that will receive the uploaded files.
  3. (optional) Set RemoveUrl to the endpoint URL that will receive the file names to delete.
  4. Configure the allowed file types via AllowedExtensions. Use a List<string>.
  5. Set MaxFileSize in bytes (int). Note that web servers have their own request size restrictions.

Steps 4 and 5 are optional, but strongly recommended.

Sample Upload configuration

<TelerikUpload SaveUrl="/api/upload/save"
               RemoveUrl="/api/upload/remove"
               AllowedExtensions="@AllowedFileTypes"
               MaxFileSize="@MaxFileSize" />

@code {
    private List<string> AllowedFileTypes { get; set; } = new List<string>() { ".jpg", ".jpeg", ".png", ".gif" };
    private int MaxFileSize { get; set; } = 10 * 1024 * 1024; // 10 MB
}

Implement Controller Methods

  • Save action method
    • Its argument should be IFormFile or IEnumerable<IFormFile>.
    • The Upload always sends files one by one, but both argument types can work.
    • The argument name (FormData request key) must match the Upload SaveField parameter value. By default, that is files.
    • The method name should match the last part of the SaveUrl value.
  • Remove action method
    • Its argument should be string or IEnumerable<string>.
    • The argument name (FormData request key) must match the Upload RemoveField parameter value. By default, that is files.
    • The method name should match the last part of the RemoveUrl value.

Both action methods should accept POST requests. Correct request routing depends on the application.

The UploadController class below assumes that the project name and namespace is TelerikBlazorUpload.

Make sure to enable controller routing in the app startup file (Program.cs). In this case, app.MapDefaultControllerRoute(); is all that's needed.

Also check the Upload Troubleshooting page.

Sample Upload Controller

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace TelerikBlazorUpload.Controllers
{
    [Route("api/[controller]/[action]")]
    public class UploadController : Controller
    {
        public IWebHostEnvironment HostingEnvironment { get; set; }

        public UploadController(IWebHostEnvironment hostingEnvironment)
        {
            HostingEnvironment = hostingEnvironment;
        }

        [HttpPost]
        public async Task<IActionResult> Save(IFormFile files) // "files" matches the Upload SaveField value
        {
            if (files != null)
            {
                try
                {
                    // save to wwwroot - Blazor Server only
                    var rootPath = HostingEnvironment.WebRootPath;
                    // save to Server project root - Blazor Server or WebAssembly
                    //var rootPath = HostingEnvironment.ContentRootPath;
                    var saveLocation = Path.Combine(rootPath, files.FileName);

                    using (var fileStream = new FileStream(saveLocation, FileMode.Create))
                    {
                        await files.CopyToAsync(fileStream);
                    }
                }
                catch (Exception ex)
                {
                    Response.StatusCode = 500;
                    await Response.WriteAsync($"Upload failed.");
                }
            }

            return new EmptyResult();
        }

        [HttpPost]
        public async Task<IActionResult> Remove(string files) // "files" matches the Upload RemoveField value
        {
            if (files != null)
            {
                try
                {
                    // delete from wwwroot - Blazor Server only
                    var rootPath = HostingEnvironment.WebRootPath;
                    // delete from Server project root - Blazor Server or WebAssembly
                    //var rootPath = HostingEnvironment.ContentRootPath;
                    var fileLocation = Path.Combine(rootPath, files);

                    if (System.IO.File.Exists(fileLocation))
                    {
                        System.IO.File.Delete(fileLocation);
                    }
                }
                catch (Exception ex)
                {
                    Response.StatusCode = 500;
                    await Response.WriteAsync($"Delete failed.");
                }
            }

            return new EmptyResult();
        }
    }
}

Security

The Telerik Upload component makes XHR requests from the browser to the designated endpoints. If needed, use the OnUpload and OnRemove events to add headers, authentication tokens and custom data to the request.

Authentication and authorization depends on the application.

File upload controllers can create application vulnerabilities. Learn about all possible security risks and how to avoid them. Do not trust any part of the upload request and implement server-side validation.

The controller methods in this documentation do not implement security measures for simplicity and brevity.

Cross-Origin Requests

Cross-origin (CORS) requests depend on the application and endpoint setup. The Upload WithCredentials parameter sets the corresponding parameter of the XHR request. Cookies, headers and other parameters of the Blazor app and CORS endpoint should be implemented by the respective applications (for example, set the Access-Control-Allow-Origin header with an appropriate value and the Access-Control-Allow-Credentials header with a true value). Read more in this CORS Tutorial. Also check this forum thread, which shows one way to setup the CORS requests, headers and responses on the receiving server.

Validation

The Upload includes built-in client-side validation for the file size and type (extension). Additional custom validation can take place in the OnSelect event.

Templates

You can use the functionality of the built-in template and modify the appearance of the Select files... button. Read more about the Telerik Upload templates...

Large File Uploads

The Upload MaxFileSize parameter is used only for client-side validation. The component sends files in one piece and the server needs a separate configuration to support large file uploads. Here are some examples for common server settings:

Drag-and-Drop File Support

The Upload provides built-in file drag-and-drop support, which allows users to drag one or multiple files and drop them anywhere in the component. The OnSelect and OnUpload events are raised upon dropping the file. You can handle this behavior to perform further actions with the selected file.

Additionally, you can define an external drop zone by using the Telerik UI for Blazor DropZone component.

Upload Parameters

The following table lists the Upload parameters. Also check the Upload API Reference for a full list of properties, methods and events.

Parameter Type and Default Value Description
Accept string The accept HTML attribute of the file <input>. It controls what file types and MIME types the browser will allow users to select. Compare with AllowedExtensions.
AllowedExtensions List<string> The list of allowed file types. The component will check if the selected files are compliant after selection. Compare with Accept. Read more at Validation.
AutoUpload bool
(true)
When true, the upload process starts automatically after file selection. When false, the component renders an upload button.
Capture string The capture HTML attribute of the <input type="file" /> element. It enables users to provide a file directly from their device camera.
Class string Renders a custom CSS class to the <div class="k-upload"> element.
DropZoneId string The id that is used to connect the Upload to an external DropZone. Assign a value matching the Id of the DropZone you are connecting the component with.
Enabled bool
(true)
Enables file selection and upload.
Id string Renders an id attribute to the <input type="file" /> element. Can be used together with a <label>.
Multiple bool
(true)
Sets if the user can select several files at the same time. The component always uploads files one by one, and the controller method receives them separately.
RemoveField string
("files")
Sets the FormData key, which contains the file name submitted for deletion to the RemoveUrl endpoint. The RemoveField value must match the delete controller method's argument name. The user triggers remove requests when clicking on the [x] buttons in the uploaded file list.
RemoveUrl string The URL which receives the file names for deletion.
SaveField string
("files")
Sets the FormData key, which contains the file submitted to the SaveUrl endpoint. The SaveField value must match the save controller method's argument name.
SaveUrl string The URL which receives the uploaded files. SaveUrl and RemoveUrl cannot change between file selection and file upload, because the component will be recreated and the selected files will be lost.
WithCredentials bool Controls if the Upload will send credentials such as cookies or HTTP headers for cross-site requests. See XMLHttpRequest.withCredentials. On the other hand, use the OnUpload and OnRemove events to add authentication tokens and other metadata to the component requests.

Upload Reference and Methods

The Upload exposes methods for programmatic operation. To use them, define a reference to the component instance with the @ref attribute (example below). The Upload methods are:

Method Description
ClearFiles Clears all files from the list, both uploaded and in queue.
OpenSelectFilesDialog Shows the browser's file selection dialog. This method doesn't work in Safari due to browser security restrictions.
UploadFiles Uploads all valid selected files. Fires the OnUpload event.

Get reference to the Upload and execute methods

<p>
    <TelerikButton OnClick="@SelectFiles">Open File Selection Dialog</TelerikButton>
    <TelerikButton OnClick="@Clear">Clear File List</TelerikButton>
    <TelerikButton OnClick="@Upload">Start Upload</TelerikButton>
</p>

<TelerikUpload @ref="@UploadRef"
               SaveUrl="/api/upload/save"
               RemoveUrl="/api/upload/remove"
               AutoUpload="false" />

@code {
    private TelerikUpload UploadRef { get; set; }

    private void SelectFiles()
    {
        UploadRef.OpenSelectFilesDialog();
    }

    private void Clear()
    {
        UploadRef.ClearFiles();
    }

    private void Upload()
    {
        UploadRef.UploadFiles();
    }
}

Troubleshooting

The Upload component requires integration with remote endpoints and controller methods to work. See how to detect and troubleshoot issues with the endpoint implementation, and how to fix them.

Next Steps

See Also

In this article