Skip to content

06 - File Upload

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;
    private readonly IWebHostEnvironment _env;

    // inject IWebHostEnvironment - we get the current dir info from it
    public HomeController(ILogger<HomeController> logger, IWebHostEnvironment env)
    {
        _logger = logger;
        _env = env;
    }
1
2
3
4
public IActionResult Upload()
{
    return View();
}
1
2
3
4
5
6
namespace WebApp.Areas.Admin.ViewModels;

public class FileUploadViewModel
{
    public IFormFile File { get; set; } = default!;
}

Form must have enctype="multipart/form-data" for file uploads to work!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@model WebApp.Areas.Admin.ViewModels.FileUploadViewModel

<h1>Upload image file!</h1>

<hr/>
<div class="row">
    <div class="col-md-4">
        <form method="post" asp-action="Upload" enctype="multipart/form-data">

            <div asp-validation-summary="All" class="text-danger"></div>

            <div class="form-group">
                <label asp-for="File" class="control-label"></label>
                <input asp-for="File" class="form-control"/>
                <span asp-validation-for="File" class="text-danger"></span>
            </div>

            <div class="form-group">
                <input type="submit" value="Upload" class="btn btn-primary"/>
            </div>
        </form>
    </div>
</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
[HttpPost]
public async Task<IActionResult> Upload(FileUploadViewModel vm)
{
    var fileExtensions = new string[]
    {
        ".png", ".jpg", ".bmp", ".gif"
    };

    if (ModelState.IsValid)
    {
        // validate file
        if (vm.File.Length > 0 && fileExtensions.Contains(Path.GetExtension(vm.File.FileName)))
        {
            // todo - scale, etc, check content etc

            // get the wwwroot full location
            var uploadDir = _env.WebRootPath;

            // figure out filename, most likely do not use client provided filename....
            var filename = Guid.NewGuid().ToString() + "_" + Path.GetFileName(vm.File.FileName);

            // final full location - wwwroot/uploads/....
            var filePath = uploadDir + Path.DirectorySeparatorChar + "uploads" + Path.DirectorySeparatorChar + filename;

            await using (var stream = System.IO.File.Create(filePath))
            {
                await vm.File.CopyToAsync(stream);
            }

            // TODO: save info db, etc
            return RedirectToAction(nameof(ListFiles));
        }

        ModelState.AddModelError(nameof(FileUploadViewModel.File), "This is not a image file! " + vm.File.FileName);
    }

    return View(vm);
}