asp.netentity-frameworkvalidationasp.net-core-mvccrud

ASP.NET 6 input validation: unique column on create - but validation problem on update


I have a table with key Id, and have a unique column (Name). When creating a new row, the Name must be unique. I created a custom validator.

public class UniqueNameValidationAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value,
            ValidationContext validationContext)
        {
            var context = (ApplicationDbContext)validationContext.GetService(typeof(ApplicationDbContext));
            if (!context.Recipes.Any(a => a.Name == value.ToString()))
            {
                return ValidationResult.Success;
            }
            return new ValidationResult("Ezzel a névvel már létre van hozva recept!");
        }
    }

Added to the model property:

[UniqueNameValidation]
public string Name { get; set; } = "";

Site code (create and edit site codes are same):

<div class="mb-3">
            <label asp-for="Name">Típus neve</label>
            <input asp-for="Name" class="form-control" />
            <span asp-validation-for="Name" class="text-danger"></span>
</div>

Code from controller when POST create:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(RecipeTableModel obj)
{
            if (ModelState.IsValid)
            {
                _db.Recipes.Add(obj);
                _db.SaveChanges();
                return RedirectToAction("Index");
            }
            else
            {
                return View(obj);
            }

}

Code from controller when POST update:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Edit(RecipeTableModel obj)
{
            if (ModelState.IsValid)
            {
                _db.Recipes.Update(obj);
                _db.SaveChanges();
                return RedirectToAction("Index");
            }
            else
            {
                return View(obj);
            }

}

It works well when I try to create a new row with an existing name, I get the error message. But I get the same "Already exists" error message when I try to update the row.

How can I solve this?


Solution

  • From your code I guess it's about server validation, to void the same "Already exists" error messages when try to update the row, you can check the Name, if it not change, remove the model state error, you can modify your Edit method refer to the below code:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public IActionResult Edit(RecipeTableModel obj)
    { 
      var dbobj =   _db.Recipes.AsNoTracking().FirstOrDefault(x => x.Id == 
       obj.Id);
        if (dbobj.Name == obj.Name)
         {
            ModelState.ClearValidationState("Name");
            ModelState.MarkFieldValid("Name");
         }
                if (ModelState.IsValid)
                {
                    _db.Recipes.Update(obj);
                    _db.SaveChanges();
                    return RedirectToAction("Index");
                }
                else
                {
                    return View(obj);
                }
    
    }
    

    result:

    enter image description here