I have tried consistently to upload a image in asp.net core yet no matter how I do it I run into the same problem. ModelState.IsValid
returns false. I eventually caved and just copied and pasted someone else's work in the hope that if I could just get it to work, even if it was someone else's, I could understand where I was going wrong. Even with my script kiddie technique, my plans were foiled. So now I have come to people who are smarter than I'll ever be.
This is the tutorial that I copied from
My model looks like this:
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
public class ImageModel
{
[Key]
public int ImageId { get; set; }
[Column(TypeName = "nvarchar(50)")]
public string Title { get; set; }
[Column(TypeName = "nvarchar(100)")]
[DisplayName("Image Name")]
public string ImageName { get; set; }
[NotMapped]
[DisplayName("Upload File")]
public IFormFile ImageFile { get; set; }
}
The relevant part of my controller
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ImageId,Title,ImageFile")] ImageModel imageModel)
{
var errors = ModelState.Values.SelectMany(v => v.Errors);
if (ModelState.IsValid)
{
// Save image to wwwroot/image
string wwwRootPath = _hostEnvironment.WebRootPath;
string fileName = Path.GetFileNameWithoutExtension(imageModel.ImageFile.FileName);
string extension = Path.GetExtension(imageModel.ImageFile.FileName);
imageModel.ImageName = fileName = fileName + DateTime.Now.ToString("yymmssfff") + extension;
string path = Path.Combine(wwwRootPath + "/Image/", fileName);
using (var fileStream = new FileStream(path, FileMode.Create))
{
await imageModel.ImageFile.CopyToAsync(fileStream);
}
// Insert record
_context.Add(imageModel);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(imageModel);
}
And finally the view
@model ImageModel
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>ImageModel</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly" class="text-danger"></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="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="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{
await Html.RenderPartialAsync("_ValidationScriptsPartial");
}
}
I have taken a look at this question and followed the suggestion. The error that it returns is
ModelError,ModelError.Exception,ModelError.ErrorMessage Microsoft.AspNetCore.Mvc.ModelBinding.ModelError
The Image Name field is required
Thank you for your time