I am attempting to add a feature which allows users to upload a photo of their pets. I am new to MVC and am using this tutorial as guidance: https://www.codaffection.com/asp-net-core-article/asp-net-core-mvc-image-upload-and-retrieve/
View:
@model PetPhotoModel;
@{
ViewData["Title"] = "Upload A photo of your pet";
}
<div class="row">
<div class="col-md-4">
<form asp-action="UploadPhoto">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="PetName" class="control-label"></label>
<input asp-for="PetName" class="form-control" />
<span asp-validation-for="PetName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Description" class="control-label"></label>
<input asp-for="Description" class="form-control" />
<span asp-validation-for="Description" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ImageFile" class="control-label"></label>
<input asp-for="ImageFile" accept="image/*" />
<span asp-validation-for="ImageFile" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="UploadPhoto" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Controller (partial):
...
public IActionResult UploadPhoto()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> UploadPhoto([Bind("Id,PetName,Title,Description,ImageFile")] PetPhotoModel petPhotoModel)
{
if (ModelState.IsValid)
{
//Save image to wwwroot/image
string wwwRootPath = _hostEnvironment.WebRootPath;
string fileName = Path.GetFileNameWithoutExtension(petPhotoModel.ImageFile.FileName);
string extension = Path.GetExtension(petPhotoModel.ImageFile.FileName);
petPhotoModel.ImageName = fileName = fileName + DateTime.Now.ToString("yymmssfff") + extension;
string path = Path.Combine(wwwRootPath + "/Image/", fileName);
using (var fileStream = new FileStream(path, FileMode.Create))
{
await petPhotoModel.ImageFile.CopyToAsync(fileStream);
}
//GetLoggedInUser() gets the current user by id from the db context
GetLoggedInUser().Uploads.Add(petPhotoModel);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(petPhotoModel);
}
...
The UserModel
contains a collection of PetPhotoModel
in order to create a 1 to many relationship in the database:
public virtual ICollection<PetPhotoModel> Uploads { get; set; }
PetPhotoModel:
public class PetPhotoModel
{
private DateTime _dateUploaded = DateTime.Now;
public int Id { get; set; }
[Required]
public string PetName { get; set; }
[Required]
public string Title { get; set; }
public string Description { get; set; }
[Column(TypeName = "nvarchar(100)")]
[DisplayName("Image Name")]
public string ImageName { get; set; }
[NotMapped]
[DisplayName("Upload File")]
public IFormFile ImageFile { get; set; }
public DateTime DateUploaded
{
get { return _dateUploaded; }
set { _dateUploaded = value; }
}
...
The issue is after the submit button is pressed that the controller does not get any data about image from the view at all despite the image being uploaded in the view:
[
question from:
https://stackoverflow.com/questions/65919982/net-core-mvc-nullreferenceexception-in-controller-when-attempting-to-upload-im 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…