Drag & Drop File Upload In Angular Using .NET Core API

Drag & Drop File Upload In Angular Using .NET Core API

In this article, we will learn how to implement drag and drop file upload in an angular application.

So, let's start with the implementation

Let's start by developing a file upload API using .NET Core.

First, we need to create the Upload API controller and add the FileUpload method using the following code.

using System;
using System.IO;
using System.Net.Http.Headers;
using Microsoft.AspNetCore.Mvc;

namespace Drag_Drop_File_Upload.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UploadController : ControllerBase
    {
        [HttpPost]
        public IActionResult FileUpload()
        {
            try
            {
                if (Request.Form.Files.Count == 1)
                {
                    var file = Request.Form.Files[0];
                    string folderName = "Upload";
                    string newPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", folderName);
                    if (!Directory.Exists(newPath))
                    {
                        Directory.CreateDirectory(newPath);
                    }
                    if (file.Length > 0)
                    {
                        string fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
                        string fullPath = Path.Combine(newPath, fileName);
                        using (var stream = new FileStream(fullPath, FileMode.Create))
                        {
                            file.CopyTo(stream);
                        }
                    }
                    return Ok();
                }
                else
                {
                    return NotFound();
                }
            }
            catch (Exception)
            {
                return BadRequest();
            }
        }
    }
}

To enable CORS requests from any origin, edit the Startup.cs file and add the following code to it.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace Drag_Drop_File_Upload
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddCors();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            // global cors policy
            app.UseCors(x => x
                .AllowAnyMethod()
                .AllowAnyHeader()
                .SetIsOriginAllowed(origin => true));

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

Our API is ready to use, now we start the front-end part in the angular application.

We need to create a new angular application using the following command in the terminal.

ng new drag-drop-file-upload

We need to create a new interface using the following command in the terminal.

ng g i HandleFile

Now, add the following code under the handle-file.ts file.

import { SafeUrl } from '@angular/platform-browser';

export interface HandleFile {
    file: File;
    url: SafeUrl;
}

We need to create a DragDrop directive using the following command in the terminal.

ng g d DragDrop

Now, add the following code under the drag-drop.directive.ts file

import { Directive, Output, EventEmitter, HostBinding, HostListener } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { HandleFile } from './handle-file';

@Directive({
  selector: '[appDragDrop]'
})
export class DragDropDirective {
  @HostBinding('style.background') public bg = '#000000';
  @Output('file') file: EventEmitter<HandleFile> = new EventEmitter();
  constructor(private sanitizer: DomSanitizer) { }
  @HostListener('dragover', ['$event']) public onDragOver(e: DragEvent) {
    e.preventDefault();
    e.stopPropagation();
    this.bg = '#999';
  }
  @HostListener('dragleave', ['$event']) public onDragLeave(e: DragEvent) {
    e.preventDefault();
    e.stopPropagation();
    this.bg = '#000000';
  }
  @HostListener('drop', ['$event']) public onDrop(e: DragEvent) {
    e.preventDefault();
    e.stopPropagation();
    this.bg = '#000000';
    const droppedFile = e.dataTransfer.files[0];
    const url = this.sanitizer.bypassSecurityTrustUrl(window.URL.createObjectURL(droppedFile));
    let handleFile: HandleFile = {
      file: droppedFile,
      url: url
    };
    this.file.emit(handleFile);
  }
}

With the help of @HostListner, we used the dragover, dragleave, and drop events in DragDropDirective. In order to display the URL of the files in the <image> tag, we also used DomSanitizer.

Now, open the app.module.ts file and import the DragDropDirective using the following code.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { DragDropDirective } from './drag-drop.directive';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent,
    DragDropDirective
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Now, add the following code under the app.component.html file.

<div appDragDrop (file)="dragDropFile($event)" style="height: 300px; text-align: center;">
    <h1 style="color: white;">Drag & Drop File Upload</h1>
    <div *ngIf="droppedFile != null">
        <img [src]="droppedFile.url" height="200" width="200" />
        <br>
        <button (click)="uploadFile()">Upload</button>
    </div>
</div>

Now, add the following code under the app.component.ts file.

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { HandleFile } from './handle-file';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Drag-Drop-File-Upload';
  droppedFile: HandleFile;
  formData = new FormData();

  constructor(private http: HttpClient) { }

  dragDropFile(file: HandleFile) {
      this.droppedFile = file;
  }
  uploadFile() {
    this.formData.append('photo', this.droppedFile.file);
    return this.http.post('https://localhost:44155/api/Upload', this.formData).subscribe(      
      (response) => {        
        alert('File Uploaded Successfully')
      },
      (error) => {        
        alert('Something Went Wrong !!!')
      }
    );
  }
}

Now, run the application using the ng serve command into the terminal and see the browser screen, we are able to upload files using drag and drop.

Conclusion

In this article, we learned how to implement drag and drop file upload in the angular application using .Net Core API.

I hope this article helps you and you will like it.👍

Please give your valuable feedback and comments or suggestion in the comment section

If you have any questions or confusion, then feel free to ask in the comment section.

Post a Comment

Previous Post Next Post