ASP.NET 6 输入验证:创建时出现唯一列 - 但更新时出现验证问题

问题描述 投票:0回答:1

我有一个带有键 Id 的表,并且有一个唯一的列(名称)。创建新行时,名称必须是唯一的。我创建了一个自定义验证器。

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!");
        }
    }

添加到模型属性:

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

站点代码(创建和编辑站点代码相同):

<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>

POST 创建时来自控制器的代码:

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

}

POST 更新时来自控制器的代码:

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

}

当我尝试使用现有名称创建新行时,它运行良好,但收到错误消息。但当我尝试更新行时,我收到相同的“已存在”错误消息。

我该如何解决这个问题?

asp.net entity-framework validation asp.net-core-mvc crud
1个回答
1
投票

从您的代码中我猜这与服务器验证有关,为了在尝试更新行时消除相同的“已存在”错误消息,您可以检查名称,如果没有更改,请删除模型状态错误,您可以修改您的编辑方法参考以下代码:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Edit(RecipeTableModel obj)
{ 
  var dbobj =  _context.Department.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);
            }

}

结果:

© www.soinside.com 2019 - 2024. All rights reserved.