In this article, let’s go through one of the most searched queries on Google, “File Upload in ASP.NET Core MVC”. Uploading Images or other documents is a very basic and common requirement when it comes to building anything from a simple application to an enterprise-level solution. Let’s build a small application with which you could upload files of any type to a file system location or to a centralized database table.
File Upload is quite important for any kind of application, right from saving a User’s Profile Picture to storing some important documents. Files can be uploaded to either the Server’s Storage or to a Centralized Database. You can find the completed source code on my GitHub Repo.
In this guide, We will build together an ASP.NET Core MVC application that can upload files to both disk and database. In this way, we will get to see the entire process behind the build and add certain extra features along the way. I will be using Visual Studio 2019 Community as my IDE.
Setting up the ASP.NET Core MVC Project
Open up VS and create a new ASP.NET Core 3.1 Application with the MVC (Model-View-Controller) Templated Web Application. As our data access layer, we will use the Entity Framework Core (Code First Approach) as our ORM as it is pretty neat and efficient to set up.
File Model
We know beforehand, that we will be uploading to either the disk or to a database. Hence we will need 2 Models. These 2 models will have almost the same properties like file name, extension, created on, description, etc. These models will only vary at the following 2 properties.
- File Path - This property will be used by the model that is responsible to hold the details of the file that is on the disk.
- File Data - Whereas this property will be needed only for the model related to file in the database, as we will be converting the file to a byte array and storing this array to the data source,
Therefore, we will build an abstract class that has the common properties. Let’s call it FileModel.
Create a new class, Models/FileModel.cs. This will be the base class.
Now, let’s create a model for the file on the file system. Name it Models/FileOnFileSystem.cs and inherit the FileModel class.
Similarly add another class for the file on database, Models/FileOnDatabaseModel.cs
Now that we have built our models, let’s connect it to a database via Entity Framework Core.
Setting up Entity Framework Core
New to Entity Framework Core - Code First Approach?
Read the detailed guide on Getting Started with Entity Framework Core in ASP.NET Core Applications. This will cover almost everything you need to know about this awesome ORM.
First, install these packages via Package Manager Console.
Next, add a connection string to your appsetting.json file.
With that out of of the way, let’s now configure the services. Modify the Startup.cs/ConfigureServices.
Finally, let’s do the required migrations and update our database. Just run the following commands on the Package Manager Console.
You will get a done message on console. Open up SQL Server Object Explorer to check if the database and tables have been created.
What is IFormFile?
ASP.NET Core has a built in interface that facilitates file upload.
As you can see, IFormFile has several properties like Name, FileName, ContentType and a few methods to Copy the file data to a memory stream. So, the basic idea will be, a front end with a form Html tag that, on submit, click sends the list of files to a list of IFormFile interface. From here, we will do the uploading part of C#. Let’s begin by creating a new empty MVC Controller, Controllers/FileController. Now let’s add an associated view to this controller by right-clicking the index method.
Setting up the View and ViewModel
What’s a View Model?
To the View (the UI, Index.cshtml), we need to pass 2 models at a time. However, by default we can pass only a single model to any given view. This requirement brought about ViewModels. ViewModels are simple classes that have multiple classes and properties within them. For example, in this case, we need to pass a list of FileOnFileSystemModel and FileOnDatabaseModel to our view. Hence, we make a new class, a ViewModel class, Models/FileUploadViewModel.cs as below.
After that, Let’s start modifying the View Page, Views/File/Index.cshtml.
Line 1 - Here we define the available model as the created view model.
Lines 8-12 is for displaying a message/status if any exists.
Line 13 is the form tag with the method as POST and enctype attribute as multipart/form-data
. PS this is mandatory for making forms that allow file upload.
Line 14 - an Input field of type file, with the name files (this name will be used in our controllers, make sure you enter this name), an attribute that says we are going to upload multiple files at once and finally a required attribute.
Line 15 - A text field for Description. Mandatory.
Line 16 and 17 are buttons of the type submit that invoke the FILE/{Method}
Controller to upload the file(s) to DB/disk.
Next, let’s go through the 2 different models of file upload.
File Upload in ASP.NET Core MVC to File System
Edit the Index.cshtml and add these lines of code.
Line 3-6, If no records found in the FileOnFileSystem model, display a “No Records Found” message.
Line 7-38, else display the data within a bootstrap table.
Line 22-35, iterate over the list of available records and add content to the table.
Line 31,32 Add action buttons to view the file and to delete the file from the disk. These buttons will invoke a method from our File controller.
File Controller
Navigate to FileController. Make sure that you inject the ApplicaitonDbContext to the constructor of the FileController.
Initially, we will need a method that returns a View Model, FileUploadViewModel. This method will be used by the other functions in the controllers. We will call the method, LoadAllFiles.
PS, you would probably want to put such methods outside the controller, maybe in a service layer. But to keep this demonstration simple, we will add all the required functions within the controller. You could refactor the code as you would want .
Change the Index Method as follows.
Here, we are loading all the available files and passing the View Model to the View.
Let’s get started with the actual Action Method that uploads the file(s) to the Disk. Add a new HTTPost Action method that takes in a list of IFormFile (ensure that you name it files, as we have given the same name in the html part too) and description string.
Line 6 - Gets the base Path, i.e, The Current Directory of the application + /Files/. Feel free to change this to your choice.
Line 7 and 8 - Checks if the base path directory exists, else creates it.
Line 9 - Gets the file name without the extension.
Line 10 - Combines the base path with the file name.
Line 11 - Gets the extension of the file. (*.png, *.mp4, etc)
Line 14-17, If the file doesnt exist in the generated path, we use a filestream object, and create a new file, and then copy the contents to it.
Line 18-26, Create a new FileOnFileSystemModel object with required values.
Line 27 and 28, Inserts this model to the db via the context instance of efcore.
Line 31 - Loads all the File data to an object.
Line 32 - Sets a message in the TempData.
Line 33 - Redirects to the Index Action Method.
Now let’s work on the 2 button click action methods, download and delete.
DownloadFileFromFileSystem - Takes in File Id as the param, gets the corresponding records from the context instance / fileonfilesystem table. Copies the file data from the file path to a memory object, and returns the file for download/view.
DeleteFileFromFileSystem - Similarly, gets the records and deletes the file from the file system. Later we proceed to remove the corresponding record from the database as well. Finally, we redirect to the index method with a completed message.
Now let’s run our application and navigate to ../file.
I will upload a random file, give it a description and click on the upload to file system button.
So, that is done. Now let’s check the actual directory where it is supposed to be uploaded to.
It gets uploaded as we wanted. With that, let’s go to uploading file to the database.
File Upload in ASP.NET Core MVC to Database
Let’s add a new Action Method (POST) named UploadToDatabase that, similar to the previous method, takes in a list of iformfile and a description.
Line 16-20 , Creates a new MemoryStream object , convert file to memory object and appends ito our model’s object.
Else, this method is quite similar to our previous one.
Further Improvement.
It is possible to refactor this method and make a common method or something, just to reduce the lines of code. Or you could probably implement a design pattern here. (Might be overkill though.)
Now, add a method to Download the file from database.
Here, we return a file object with it’s content exactly as it is in the database. Finally we add our last method, to delete a record. It’s a quite straight forward one.
With that done, let’s do our final tests. Build and run the application. Navigate to ../File/
PS, You could add a new navigation link in the nav-menu to easily navigate to the File Controller.
I will add some sample data and description and click on uploadtodatabase button.
Pretty Cool yeah :D The idea might be simple, but we have built a near to complete utility that can potentially showcase your skills as a developer, especially for the guys who are just getting started with ASP.NET Core MVC.
Summary
We have covered the most basic topic in all of ASP.NET Core MVC by building a pretty cool tool. I hope you all enjoyed this detailed guide on File Upload in ASP.NET Core MVC. Share it within your developer community to help others as well. :D Here is the source code for the completed project. Happy Coding :D