Search code examples
c#asp.net-mvcasp.net-coreasp.net-core-mvciformfile

IFormFile is always NULL in ASP.NET Core 3.0 MVC


I have been banging my head on this one for almost 2 days now. I would appreciate any help. No matter what I do, my IFormFile is always null. Here is the MVC setup:

Razor View:

<form method="post" enctype="multipart/form-data" asp-controller="Admin" asp-action="LoadProvidersBulk">
    <h6 class="text-muted">Upload Provider File</h6>
    <h6 class="text-muted small">Supported File Types: <b>.xlsx</b></h6>

    <div class="form-group-row d-inline-flex badge-dark" style="padding-top:10px; padding-bottom:10px;">
        <div class="col-sm-4" style="padding:2px">
            <input type="file" asp-for="FormFile" name="ProviderUpload" class="form-control-sm" />
        </div>
    </div>
    <div class="form-group row" style="padding-top:10px">
        <div class="col-sm-5 text-left">
            <button class="btn btn-sm btn-dark btn-primary" type="submit">Load Providers</button>
            <a asp-action="LoadProviders" class="btn btn-sm btn-dark btn-primary">Cancel</a>
        </div>
    </div>
</form>

Model:

using SampleProject.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace SampleProject.ViewModels
{
    public class LoadProvidersBulkViewModel
    {
        public IFormFile FormFile { get; set; }
    }
}

Controller:

        [HttpPost]
        public async Task<IActionResult> LoadProvidersBulk([FromForm(Name = "ProviderUpload")] LoadProvidersBulkViewModel loadProvidersBulkViewModel, CancellationToken cancellationToken)
        {
            var file = loadProvidersBulkViewModel.FormFile;            

            if (file == null || file.Length <= 0)
            {
                ModelState.AddModelError("BulkUploadError", "The file cannot be empty");
                return View("LoadProvidersBulk");
            }

            /* Removed all other code for brevity */

            return RedirectToAction("Users", _userManager.Users);
        }

Solution

  • You mixed up asp-for and name attribute name (asp-for="FormFile" name="ProviderUpload").

    The Input Tag Helper binds an HTML <input> element to a model expression in your razor view are-

    <input asp-for="<Expression Name>">

    Generates the id and name HTML attributes for the expression name specified in the asp-for attribute. asp-for="Property1.Property2" is equivalent to m => m.Property1.Property2. The name of the expression is what is used for the asp-for attribute value.

    So your code look like-

    View:-

    @model SampleProject.ViewModels.LoadProvidersBulkViewModel
    
    
    <form method="post" enctype="multipart/form-data" asp-controller="Admin" asp-action="LoadProvidersBulk">
        <h6 class="text-muted">Upload Provider File</h6>
        <h6 class="text-muted small">Supported File Types: <b>.xlsx</b></h6>
    
        <div class="form-group-row d-inline-flex badge-dark" style="padding-top:10px; padding-bottom:10px;">
            <div class="col-sm-4" style="padding:2px">
                <input type="file" asp-for="FormFile" class="form-control-sm" />
            </div>
        </div>
        <div class="form-group row" style="padding-top:10px">
            <div class="col-sm-5 text-left">
                <button class="btn btn-sm btn-dark btn-primary" type="submit">Load Providers</button>
                <a asp-action="LoadProviders" class="btn btn-sm btn-dark btn-primary">Cancel</a>
            </div>
        </div>
    </form>
    

    Controller:-

        [HttpPost]
        public async Task<IActionResult> LoadProvidersBulk(LoadProvidersBulkViewModel model)
        {
            var file = model.FormFile;            
    
            if (file == null || file.Length <= 0)
            {
                ModelState.AddModelError("BulkUploadError", "The file cannot be empty");
                return View("LoadProvidersBulk");
            }
    
            /* Removed all other code for brevity */
    
            return RedirectToAction("Users", _userManager.Users);
        }