Introduction
This article will demonstrate how to upload an image on MVC Web App razor pages using ASP.NET Core 2.2.
Background
I found it difficult to find one blog or page describing all the required steps to upload images on a .NET Core MVC web application using Razor pages and how to list the images.
This code is available on GitHub @ https://github.com/charlesbill/TheSolutionArchitect/tree/dev-branch/test-mvc-webapp.
Using the Code
This article will demonstrate all the steps required to upload an image and view the images on a list.
To get this to work, the following prerequisites are required:
- DotNet Core 2.2 MVC Web Application created
- SQLite Database with
Products
table. Below, find the Products
table used in this example.
- You need a
ProductsController
and Views for Create
and Index
. This is not covered in this article.
Step 1
Create a folder under your wwwroot folder, called ImageFiles. Here is an example:
Step 2
Add the following lines of code to the Startup.cs class, under the ConfigurationServices
method:
services.AddSingleton<IFileProvider>(
new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/ImageFiles"))
);
Step 3
Ensure the following line is in the Configure
method:
app.UseStaticFiles();
Step 4
Open ProductsController
class, and add the following declarations variables:
private readonly IFileProvider fileProvider;
private readonly IHostingEnvironment hostingEnvironment;
Step 5
Add the two variables above as parameters in the ProductsController
initial method and set the variables:
public ProductsController(MvcWebAppDbContext context,
IFileProvider fileprovider, IHostingEnvironment env)
{
_context = context;
fileProvider = fileprovider;
hostingEnvironment = env;
}
Step 6
Add IFormFile
as a parameter to the [HttpPost]
Create
method. Here is the complete method:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("IdProduct,ProductCode,ProductType,
Description,UnitPrice,QtyInStock")] Product product, IFormFile file)
{
if (ModelState.IsValid)
{
_context.Add(product);
await _context.SaveChangesAsync();
if (file != null || file.Length != 0)
{
FileInfo fi = new FileInfo(file.FileName);
var newFilename = product.IdProduct + "_" + String.Format("{0:d}",
(DateTime.Now.Ticks / 10) % 100000000) + fi.Extension;
var webPath = hostingEnvironment.WebRootPath;
var path = Path.Combine("" , webPath + @"\ImageFiles\" + newFilename);
var pathToSave = @"/ImageFiles/" + newFilename;
using (var stream = new FileStream(path, FileMode.Create))
{
await file.CopyToAsync(stream);
}
product.ImagePath = pathToSave;
_context.Update(product);
await _context.SaveChangesAsync();
}
return RedirectToAction(nameof(Index));
}
return View(product);
}
Step 7
Go to the Create.cshtml file Views/Products and update the <form
tag. Note, the asp-controller
, method
and enctype
is added to the tag line:
<form asp-controller="Products" asp-action="Create" method="post" enctype="multipart/form-data">
Step 8
Add the following <div
. NOTE the name
called file
is the same as the parameter on the Create
within your controller:
<div class="form-group">
<div class="col-md-10">
<p>Upload a Image</p>
<input type="file" name="file" />
</div>
</div>
Step 9
Go to the Index.cshtml file and make the following changes to the <table
tag. Also, add the <th>
tag as shown below:
<table class="table" enctype="multipart/form-data">
<thead>
<tr>
<th>
Image
</th>
Step 10
Add the <img
tag to the @foreach
(var item in Model
) as shown below:
@foreach (var item in Model) {
<tr>
<td>
<img class="img-thumbnail" src="@item.ImagePath"
asp-append-version="true" alt="@item.ImagePath" />
</td>
Note, the above code uses the img-thumbnail
class. This should be available if you use the same default bootstrapper that comes with .NET Core MVC.
Here is an example of the app working:
Points of Interest
Ensure the correct folder structure is used. You can also put default folders into a configuration file. This is up to you, but be aware of the Web app's GetCurrentDirectory
?
History
- 9th May, 2019: First upload