【问题标题】:How and where to validate uniqueness of attribute/property in ASP.NET Core MVC using Entity Framework Core 6如何以及在何处使用 Entity Framework Core 6 在 ASP.NET Core MVC 中验证属性/属性的唯一性
【发布时间】:2022-02-10 10:35:30
【问题描述】:

我想检查一下,users 表记录没有存储特定的电子邮件。

如果有,则ModelState.IsValid 在控制器操作中返回 false。

我了解唯一约束的需要,并且我了解竞争条件的问题。这些不是我现在关心的问题。

此时我只想让ModelState.IsValid在正确位置查询数据并使模型无效后返回false。

我是否应该实施这样的验证:

  1. DbContext?
  2. 在我的实体类(用户/公司等)中?
  3. SomeCustomValidation类中?
  4. 直接在控制器中(因为我已经可以查询数据库...)
  5. 别处...

很好的奖励是创建可在所有实体中重复使用的解决方案 :)

我该怎么做?

【问题讨论】:

    标签: entity-framework-core asp.net-core-mvc


    【解决方案1】:

    您可以自定义验证属性,如下所示:

    public class TestEmailAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value,
            ValidationContext validationContext)
        {
            var context = (YourDbContext)validationContext.GetService(typeof(YourDbContext));
            if(!context.User.Any(a=>a.Email==value.ToString()))
            {
                return ValidationResult.Success;
            }
            return new ValidationResult("Email exists");
        }
    }
    

    型号:

    public class User
    {
        public int Id { get; set; }
        [TestEmail]
        public string Email { get; set; }
    }
    

    查看(Test.cshtml):

    @model User
    <form method="post" asp-action="Test" asp-controller="Home">   
        <div class="form-group">
            <input asp-for="Email" />
            <span asp-validation-for="Email" class="text-danger"></span>
        </div>
    
        <input type="submit" value="Post"/>
    </form>
    

    控制器:

    //GET render the Test.cshtml
    public async Task<IActionResult> Test()
    {
        return View();
    }
    [HttpPost]
    public async Task<IActionResult> Test(User user)
    {
        if(!ModelState.IsValid)
        {
            return View(user);
        }
        return RedirectToAction("Index");
    }
    

    【讨论】:

    • 您的示例确实有效,尽管需要一些 null 检查来消除警告,但我也希望 TestEmailAttribute 类将是 UniqueAttribute 动态处理 model 和 @ 987654329@。由于所有这些都在validationContext 内,我想我可以做到!谢谢你的回答。
    【解决方案2】:

    更好的方法是在每次插入或更新之前检查它:

    if(db.Table.Any(x => x.UniqueCloumn == newValue))
        error = "this record is already exist"
    else
    {  
        db.Table.Add(newObject);
        db.Savechanges() 
    }
    

    还有一些我不推荐的可重用代码方法: https://www.codeproject.com/Tips/1143215/Validate-a-Unique-Constraint-at-dbContext-Validate

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-06
      • 2021-03-31
      • 2019-05-19
      • 2020-06-27
      • 1970-01-01
      • 2023-03-17
      相关资源
      最近更新 更多