I am practice CRUD operation in ASP.NET Core 6 MVC. I try to upload single image method. The image is upload on create method. But when I try to use edit method without change in image. It give null value on Edit post method.
I make image column as string and save only the random name generated by AJAX url via javascript. On time on Create, Image upload + javascript run and get random name + save in database. But when I try to edit method, without upload new image it save as Null (the image show on edit page.)
Code for controller Edit
post method:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, CustomerMaster customerMaster, IFormCollection formData)
{
if (ModelState.IsValid)
{
try
{
if (!_context.CustomerMasters.Any(x => x.MobileNo == customerMaster.MobileNo && x.CustomerId != id))
{
CustomerMaster customer = await _context.CustomerMasters.FindAsync(id);
customer.CustomerName = customerMaster.CustomerName;
customer.MobileNo = customerMaster.MobileNo;
customer.Email = customerMaster.Email;
customer.Address = customerMaster.Address;
customer.Image = customerMaster.Image;
customer.WhenEntered = DateTime.UtcNow;
_context.Update(customer);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
else
{
ModelState.AddModelError("", "Name with same mobile no. already exists.");
}
}
return RedirectToAction(nameof(Index));
}
return View(customerMaster);
}
Here is my edit.cshtml
:
''''
@model Customer_Crud_Demo.Models.CustomerMaster
@using Customer_Crud_Demo.Common
@{
ViewData["Title"] = "Edit";
string imagePath = string.IsNullOrEmpty(Model.Image) ? "https://via.placeholder.com/200x200" : Config.customerImagePath + Model.Image.Replace(".", ".");
}
In config
customerImagePath = "/Content/MultiCustomerImg/"
edit.cshtml inside form
<form asp-action="Edit" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="CustomerId" />
<label asp-for="Image" class="control-label"></label>
<table>
<tr>
<td>
<input type="file" asp-for="Image" id="fuCustomerImage" class="fu form-control" accept=".jpg,.jpeg,.png" />
</td>
<td>
<input type="button" value="Upload" id="btnUploadImage" class="btn btn-primary" data-URL="CustomerMaster/UploadFile" data-path="/Content/CustomerImages" />
</td>
</tr>
<tr>
<td>
<span asp-validation-for="Image" class="text-danger"></span>
</td>
</tr>
<tr>
<td class="error" colspan="2">
Please upload image of 200 X 200 and size less than 150KB.
</td>
</tr>
</table>
<div class="singleImage">
<img src="@imagePath" alt="Alternate Text" id="ImgUploadedImage" height="200" width="200" />
@Html.HiddenFor(model => model.Image, new { id = "image" })
</div>
</form>
What is my mistake? Please correct me.
In your Edit.cshtml
, You have two input
tag with same Name:
1.
<input type="file" asp-for="Image" id="fuCustomerImage" class="fu form-control" accept=".jpg,.jpeg,.png" />
2.
@Html.HiddenFor(model => model.Image, new { id = "image" })
They will all generate code like <input Name="Image" ..../>
in HTML.
ModelBinding
will just bind the value of the first Input
, This is why you will get null even you don't change any in Image. You can refer to this code:
Edit.cshtml
<input type="file" Name="file" id="fuCustomerImage" class="fu form-control" accept=".jpg,.jpeg,.png" />
Edit Method
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, CustomerMaster customerMaster, IFormFile file)
{
if (ModelState.IsValid)
{
try
{
if (!_context.CustomerMasters.Any(x => x.MobileNo == customerMaster.MobileNo && x.CustomerId != id))
{
CustomerMaster customer = await _context.CustomerMasters.FindAsync(id);
customer.CustomerName = customerMaster.CustomerName;
customer.MobileNo = customerMaster.MobileNo;
customer.Email = customerMaster.Email;
customer.Address = customerMaster.Address;
if (file != null)
{
//I don't how you save file as string in database, Here i just save file name as an example
customer.Image = file.FileName
}
else
{
customer.Image = customerMaster.Image;
}
customer.WhenEntered = DateTime.UtcNow;
_context.Update(customer);
await _context.SaveChangesAsync();
}
else
{
ModelState.AddModelError("", "Name with same mobile no. already exists.");
}
}
return RedirectToAction(nameof(Index));
}
return View(customerMaster);
}