Drag and Drop Upload File to Server
Drag-n-Drop file upload in Blazor using JS interop and minimal API (Part 1)
Uploading files from customer computer to the server is a mutual task in spider web applications. You can either use jQuery Ajax or Blazor's InputFile component to achieve that task. Files to be uploaded on the server are typically selected by the end user using file input field. However, most of the browsers as well allow you to select files by dragging them from the client computer to your web application. To that end this article discusses how elevate-n-drib of files can exist done in Blazor Server apps. I am going to assume that you are familiar with Blazor'southward JavaScript interop. You lot may read my previous article in case yous aren't familiar with Blazor'south JS interop.
In this first role of the article I will discuss the elevate-n-driblet functionality with an instance. In the next part I will show how the selected files can be uploaded to the server using a minimal API or a controller based API.
Earlier we write whatsoever code that enables elevate-northward-drop of files, allow's rapidly see the sample app that we are going to build. Take a expect at the following Razor Component that makes the master page of the application.
Initially when you lot offset the app, you volition be shown a drib target where you tin elevate and drib files from the figurer. Every bit before long as you drag and drop ane or more files, their names will be listed in the drop target and the uploading performance volition begin.
Every bit you lot can encounter, there are three epitome files selected. A progress message is displayed in the drop target and also a progress indicator image is displayed to the user. Once the upload is complete a success message will be displayed as follows:
Now that you know how the app is going to work, let's start building information technology.
Brainstorm by creating a new Blazor Server app using Visual Studio.
So add a new Razor Component named FileUpload.razor to the Pages folder.
Also add a new JavaScript file named JavaScript.js in the wwwroot/Scripts binder. We volition utilise some JS interop code that will be housed in this JavaScript file.
Then add jQuery library file to the www/Scripts binder. Nosotros will use jQuery Ajax for the sake of uploading the selected files to the server.
Then add a <script> reference to both of these files in the _Host.cshtml file equally shown below:
<script src="~/scripts/jquery-ii.1.1.min.js"></script> <script src="~/scripts/JavaScript.js"></script>
Then open up FileUpload.razor component and write the following directives to it.
@page "/fileupload" @inject IJSRuntime JS
The @page directive sets the route for the component to /fileupload so that it tin be accessed as a standalone "page". And so we inject IJSRuntime object because nosotros want to use JS interop features afterwards. This injected object tin be accessed in our lawmaking using JS property.
Then place a <div> element and an <img> element as shown below.
<div id="fileBasket" class="filebasket"> </div> <br /> <img id="progress" src="/Images/Progress.gif" />
The fileBasket element acts as a drop target where you drag-n-drop files and the progress element displays an animated GIF during upload operation. You volition need to place Progress.gif in the wwwroot/Images folder.
The filebasket CSS class applied to the fileBasket element is this:
.filebasket{ border:solid 2px black; padding:10px; acme:200px; width:250px; text-align:center; font-weight:assuming; } Y'all can place it in a CSS file (or at the top of the component file if y'all don't want to add a CSS file).
In club to implement drag-n-drop on the fileBasket <div> element, y'all need to handle three events namely dragenter, dragover, and drop. In that location are two ways to handle these events. You can handle them from your C# code by writing the necessary effect handler methods OR you lot can write them in JavaScript and wire them using Blazor'southward JS interop. I will show yous both the techniques in the following discussion.
Let'southward first handle these events using C# event handlers.
Change the <div> element as shown beneath:
<div id="fileBasket" class="filebasket" @ondrop="@OnDrop" @ondrop:preventDefault="true" @ondrop:stopPropagation="true" @ondragenter="@OnDragenter" @ondragenter:preventDefault="true" @ondragenter:stopPropagation="true" @ondragover="@OnDragover" @ondragover:preventDefault="truthful" @ondragover:stopPropagation="truthful"> </div>
Notice this markup carefully. Information technology wires three issue handlers using @ondrop, @ondragenter, and @ondragover attributes. The respective upshot handler methods OnDrop(), OnDragenter(), and OnDragover() will be written in @code block later.
Also notice that nosotros fix preventDefault and stopPropagation properties for all the 3 events to true. Since we want to use the <div> chemical element as a driblet target, nosotros demand to suppress its default behavior and hence setting these properties is necessary. If you don't prepare these properties the browser volition typically navigate to the dropped files rather than assuasive our app to handle the drop operation.
Now let's write the three event handler methods - OnDrop(), OnDragenter(), and OnDragover() in @lawmaking block.
@code { public async void OnDrop(DragEventArgs evt) { } public void OnDragenter(DragEventArgs evt) { } public void OnDragover(DragEventArgs evt) { } } Out of these 3 event handlers, nosotros volition write code only for OnDrop() but you tin use the others in case yous desire to perform some processing. All of them receive a DragEventArgs object that provides more than data almost what is existence dragged.
Now add together the following properties at the top of the @code block.
public string[] SelectedFiles { go; gear up; } public string Message { get; set; } = "Elevate-n-Drop files here."; The SelectedFiles assortment holds a list of files selected for the upload performance. This array is used to display a bulleted list of files in the fileBastet chemical element discussed earlier. The Message holding is used to display a general purpose message (say, a success message or an error message) to the user and information technology is outputted beneath the fileBasket chemical element.
And so add the following lines to the OnDrop() result handler.
public async void OnDrop(DragEventArgs evt) { this.SelectedFiles = evt.DataTransfer.Files; wait JS.InvokeVoidAsync("UploadFiles", DotNetObjectReference.Create(this)); StateHasChanged(); } Here, nosotros use DragEventArgs object's DataTransfer.Files belongings to obtain a listing of files selected by the end user. We store this list into the SelectedFile array. We and so invoke a JS function called UploadFiles() using the InvokeVoidAsync() method. Detect that current component's reference is passed to the InvokeVoidAsync() method using DotNetObjectReference.Create() method. Finally, StateHasChanged() method is chosen then that the component UI gets the updated values.
Next, open up the JavaScript.js file and add the UploadFiles() part.
function UploadFiles(compRef) { alarm("File upload API call here."); } Nosotros will add the jQuery Ajax code that invokes the API later. For the time being just put an alert for the sake of testing.
The SelectedFiles tin be displayed in the fileBasket chemical element equally shown below.
<div id="fileBasket" course="filebasket" @ondrop="@OnDrop" @ondrop:preventDefault="true" @ondrop:stopPropagation="true" @ondragenter="@OnDragenter" @ondragenter:preventDefault="truthful" @ondragenter:stopPropagation="true" @ondragover="@OnDragover" @ondragover:preventDefault="truthful" @ondragover:stopPropagation="true" > @if (SelectedFiles != null) { <div>Uploading...</div> <ul> @foreach (var file in SelectedFiles) { <li>@file</li> } </ul> } else { <potent>@Message</potent> } </div> Inside the <div> element a foreach loop iterates through the SelectedFiles array and displays a bulleted list of files. If SelectedFiles is nada, the Bulletin property is displayed.
When the jQuery Ajax lawmaking completes the file upload performance it sets a message indicating the completion of the operation. This requires that UploadFiles() calls a C# method that sets the Message property to desired value. Therefore, nosotros will add together a C# method called SetMessage() in the FileUpload.razor component.
[JSInvokable] public bool SetMessage(string msg) { Bulletin = msg; SelectedFiles = null; StateHasChanged(); return truthful; } Notice that the SetMessage() is marked with [JSInvokable] attribute making it callable from JS code. Inside, nosotros set the Message holding to the supplied message and clear the SelectedFiles assortment.
In the preceding code we handled the OnDrop event using C#. Since we will be uploading files using jQuery Ajax the UploadFiles() part needs to know what files are selected past the user for uploading. This requires that nosotros handle OnDrop event in JS code besides. Then, add another function named WireEventHandlers() in the JavaScript.js file as shown below.
part WireEventHandlers() { $("#fileBasket").on("drop", function (evt) { window.selectedFiles = evt.originalEvent.dataTransfer.files; }); } The WireEventHandlers() function wires drop event handler using jQuery on() method. The drib event handler simply stores a listing of files in the global selectedFiles variable. We volition use the selectedFiles variable in the UploadFiles() function later.
Note that DataTransfer.Files used in the C# code gives simply an assortment of file names whereas dataTransfer.files in the JS code gives list of files and can be used to admission file content during the upload functioning.
Nosotros also want to hide the progress indicator epitome initially when the component is rendered. Then, add a function named HideProgress() that does the task.
function HideProgress() { $("#progress").hide(); } We will phone call WireEventHandlers() and HideProgress() in the Razor Component's OnAfterRenderAsync() method.
protected async override Job OnAfterRenderAsync (bool firstRender) { if (firstRender) { await JS.InvokeVoidAsync("WireEventHandlers"); await JS.InvokeVoidAsync("HideProgress"); } } Then far then good. Although we haven't written any lawmaking that does the file upload, yous can cheque the elevate-n-drop behavior by running the performance. If you followed all the steps so far, you volition run into an alert followed past a list of files selected for the upload performance like this:
And
Of course, no files volition exist uploaded at this phase simply the skeleton for doing that is now ready.
In the instance discussed so far, we handled the dragenter and dragover events from Blazor code. If you desire you tin handle these ii events from JS code also. Let'due south see that possibility also.
Go to JavaScript.js file and add the following customer side event handlers to WireEventHandlers() role.
$("#fileBasket").on("dragenter", function (evt) { evt.preventDefault(); evt.stopPropagation(); }); $("#fileBasket").on("dragover", part (evt) { evt.preventDefault(); evt.stopPropagation(); }); As you can come across, nosotros are at present calling preventDefault() and stopPropagation() from the JS event handlers. Since we are cancelling the default behavior and stopping event bubbles from JS code you can remove the preventDefault and stopPropagation backdrop from the fileBasket <div> element (yous can also remove the corresponding C# empty event handler methods).
<div id="fileBasket" class="filebasket" @ondrop="@OnDrop" @ondrop:preventDefault="true" @ondrop:stopPropagation="truthful">
If y'all run the application y'all will get the same effect every bit earlier.
In the adjacent part of this article we will create a minimal API endpoint that is invoked using jQuery Ajax to upload files to the server.
That's it for now! Keep coding!!
Source: http://www.binaryintellect.net/articles/d40fbcb5-fb25-4d83-950c-47632dc632c1.aspx
0 Response to "Drag and Drop Upload File to Server"
Post a Comment