将ModelState.AddModelError添加到我的Controller类中,而不检查ModelState.Is

本文关键字:ModelState Is 类中 不检查 我的 AddModelError 添加 Controller | 更新日期: 2023-09-27 18:28:12

我读过一本关于asp.net MVC 5的书,书中提到有多种方法可以进行模型验证,例如:-

  1. 显式验证控制器中的一个模型

  2. 使用DataAnnotation

起初,我认为这两种方法具有完全相同的影响或以相同的方式行事,但我注意到以下几点:-

如果我在没有明确检查ModelState.IsValid的情况下将ModelState.AddModelError添加到我的操作方法中,那么即使存在以下模型错误,我也可以保存我的对象(我故意注释掉了ModelState.IsValid):-

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include="CountryID,Name")] Country country)
    {
        if (country.Name.StartsWith("a")) {
            ModelState.AddModelError("Name","start with A is not allowed");
       }
   // if (ModelState.IsValid){
        repository.add(country);
        repository.save();
        string s = country.Name;
        string s2 = s;
           return RedirectToAction("Index");
        //}          
    }

因此,如果我输入一个以"a"开头的Country.Name,repository.save()将不会阻止对象的保存。

而如果我替换了对Country.Name的显式检查,通过添加如下自定义元数据验证:-

public class NameCheckAttribute : ValidationAttribute
    {
        public override bool IsValid(object value)
        {
            return  !value.ToString().StartsWith("a");
        }
    }

然后CCD_ 4;当它试图添加新的国家/地区时,即使我没有检查ModelState.IsValid ,也会引发以下异常

Server Error in '/' Application.
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details. 
  Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 
 Exception Details: System.Data.Entity.Validation.DbEntityValidationException: Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
Source Error: 

Line 5109:        public void Save()
Line 5110:        {
Line 5111:            tms.SaveChanges();
Line 5112:        }
Line 5113:

因此,这意味着这两种方法的作用方式并非100%相同,因为如果对象违反了dataannotation检查,则使用dataannotation将阻止添加对象,而在Controller中添加ModelState.AddModelError将不会阻止保存对象(当然,除非我在保存对象之前检查ModelState.IsValid!)。有人能对此提出建议吗?感谢

将ModelState.AddModelError添加到我的Controller类中,而不检查ModelState.Is

这是因为在保存实体时,实体框架将根据DataAnnotations和数据类型规则(例如,不能将字符串保存为int)对模型执行自己的验证(保持此高级别)。

当您人为地注入ModelState错误,然后不检查.IsValid()属性时,Entity Framework将只遵循域模型的规则。

其中最大的一点是,控制器将返回的表单值绑定到模型。如果不进行.IsValid()检查,则数据将传递给Entity Framework,它对绑定的ModelState一无所知,包括手动注入的表单中的ModelState错误,而只知道它试图保存的实际域模型的规则。

ModelState.AddModelError仅向现有ModelState添加错误。使用AddModelError手动添加错误消息对于来自业务逻辑检查的自定义错误消息非常有用。添加ModelError不会对数据进行验证,也不会阻止您保存数据;它实际上只是一种从各种来源收集错误的机制。

DataAnnotations是关于验证数据的。在HttpPost过程中创建对象时会检查DataAnnotations,在使用EntityFramework将数据存储在数据库中时会再次检查。通过DataAnnotation检查失败的对象可以生成ModelError,并将ModelState标记为Invalid。