'IFormFile is always null in ASP.NET Core 3.1 MVC
I have been sitting at my desk for several days, reading through Google searches, trying to get my ASP.Net Core application to upload files to physical location, and store the filename in the database. However whenever I try to upload a file, the IFormFile always returns a null. I'm fairly new to this.
Here is the view code
<div class="col-md-4">
<form method="post" enctype="multipart/form-data" asp-controller="Quiz" asp-action="Create" >
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="QuizTitle" class="control-label"></label>
<input asp-for="QuizTitle" class="form-control" />
<span asp-validation-for="QuizTitle" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Category" class="control-label"></label>
<input asp-for="Category" class="form-control" />
<span asp-validation-for="Category" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Author" class="control-label"></label>
<input asp-for="Author" class="form-control" />
<span asp-validation-for="Author" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="QuizPdf" class="control-label"></label>
<input asp-for="QuizPdf" class="form form-control">
<span asp-validation-for="QuizPdf" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary mt-3" />
</div>
</form>
The controller code
public IActionResult Create()
{
return View();
}
// POST: Quiz/Create
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([FromForm]IFormFile PostedFile, QuizDetailsModel quizDetailsModel)
{
if (ModelState.IsValid)
{
if (quizDetailsModel.QuizPdf != null)
{
string folder = "files/pdfs/";
folder += quizDetailsModel.QuizPdf.FileName;
quizDetailsModel.QuizPdfUrl = folder;
string serverFolder = Path.Combine(_webHostEnvironment.WebRootPath, folder);
await quizDetailsModel.QuizPdf.CopyToAsync(new FileStream(serverFolder, FileMode.Create));
}
_context.Add(quizDetailsModel);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(quizDetailsModel);
}
and the model code
public class QuizDetailsModel
{
public int Id { get; set; }
[Required(ErrorMessage = "Please enter a quiz title.")]
[Display(Name = "Title")]
public string QuizTitle { get; set; }
[Required(ErrorMessage = "Please select a category.")]
public string Category { get; set; }
[Required(ErrorMessage = "Please enter a quiz author")]
public string Author { get; set; }
[Display(Name = "Upload quiz pdf.")]
[Required]
[NotMapped]
public IFormFile? QuizPdf { get; set; }
public string QuizPdfUrl { get; set; }
[Display(Name = "Date Added")]
[DisplayFormat(DataFormatString = "{0:MMMM dd, yyyy")]
[DataType(DataType.Date)]
public DateTime DateAdded { get; set; } = DateTime.Now;
public List<QuestionsAnswersModel> QuestionsAnswers { get; set; } = new List<QuestionsAnswersModel>();
Solution 1:[1]
The parameter is called PostedFile, the field name is called QuizPdf do you think those are the same?
Update your code like below. remove [FromForm] no need this and also change your parameter name PostedFile to QuizPdf
public async Task<IActionResult> Create(IFormFile QuizPdf , QuizDetailsModel quizDetailsModel)
{
//clarify code
}
It will definitely resolve your issue.
Solution 2:[2]
Share my recent research on files and improve my previous imperfect answer, sorry I solved it so late.@titch2019
Below is the demo:
MultipleFile:
public class MultipleFile
{
[Key]
public string Name { get; set; }
public List<IFormFile> Photo { get; set; }
}
Index:
@model MultipleFile
<form asp-action="Index" enctype="multipart/form-data" >
<div class="form-group">
<label asp-for="Photo" class="control-label"></label>
<input type="file" asp-for="Photo" class="form-control" multiple />
<span asp-validation-for="Photo" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
MutiController:
public class MutiController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpPost]
public IActionResult Index(MultipleFile multipleFile, List<IFormFile> Photo)
{
return View();
}
}
Result:
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Qing Guo |

