C# ModelState.IsValid做什么?

C# ModelState.IsValid做什么?,c#,asp.net-mvc,C#,Asp.net Mvc,当我执行create方法时,我在参数中绑定我的对象,然后检查ModelState是否有效,因此我将添加到数据库: 但是,当我需要在添加到数据库之前更改某些内容时(在更改之前,ModelState无效,因此我必须这样做) 为什么模型状态仍然无效 这个函数究竟检查什么 这是我的例子: [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create([Bind(Include = "EncaissementID,libelle,Date

当我执行create方法时,我在参数中绑定我的对象,然后检查
ModelState
是否有效,因此我将添加到数据库:

但是,当我需要在添加到数据库之前更改某些内容时(在更改之前,
ModelState
无效,因此我必须这样做) 为什么模型状态仍然无效

这个函数究竟检查什么

这是我的例子:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "EncaissementID,libelle,DateEncaissement,Montant,ProjetID,Description")] Encaissement encaissement) {
  encaissement.Montant = Convert.ToDecimal(encaissement.Montant);
  ViewBag.montant = encaissement.Montant;
  if (ModelState.IsValid) {
    db.Encaissements.Add(encaissement);
    db.SaveChanges();
    return RedirectToAction("Index", "Encaissement");
  };
  ViewBag.ProjetID = new SelectList(db.Projets, "ProjetId", "nomP");
  return View(encaissement);
}

ModelState.IsValid
基本上会根据添加到模型属性的数据注释,告诉您发布到服务器的数据是否存在任何问题

例如,如果您有一个
[必需(ErrorMessage=“Please fill”)]
,并且当您将表单发布到服务器时该属性为空,则ModelState将无效

ModelBinder还为您检查一些基本内容。例如,如果您有一个生日日期选择器,并且该选择器绑定到的属性不是可为空的
DateTime
类型,则如果您将日期保留为空,则您的模型状态也将无效


,和是一些有用的文章。IsValid表示是否可以将来自请求的传入值正确绑定到模型,以及在模型绑定过程中是否违反了任何明确指定的验证规则

在您的示例中,被绑定的模型是类类型
Encaissement
。验证规则是通过使用
IValidatableObject
Validate()
方法中添加的属性、逻辑和错误在模型上指定的规则,或者只是在操作方法的代码中指定的规则

如果值能够正确绑定到模型,并且在此过程中没有违反任何验证规则,则
IsValid
属性将为true

下面是如何在模型类上实现验证属性和
IValidatableObject
的示例:

public class Encaissement : IValidatableObject
{
    // A required attribute, validates that this value was submitted    
    [Required(ErrorMessage = "The Encaissment ID must be submitted")]
    public int EncaissementID { get; set; }

    public DateTime? DateEncaissement { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var results = new List<ValidationResult>();

        // Validate the DateEncaissment
        if (!this.DateEncaissement.HasValue)
        {
            results.Add(new ValidationResult("The DateEncaissement must be set", new string[] { "DateEncaissement" });
        }

       return results;
    }
}
值得注意的是,模型属性的值类型也将得到验证。例如,不能将字符串值指定给
int
属性。如果这样做,它将不会被绑定,错误也将添加到您的
ModelState

在您的示例中,
EncaissementID
值不能将值
“Hello”
发布到它,这将导致添加模型验证错误,
IsValid
将为false


正是由于上述任何原因(可能还有更多原因),模型状态的
IsValid
bool值将
false

您可以找到一篇关于模型状态及其使用的精彩文章

具体来说,
IsValid
属性是一种快速检查
ModelState.errors
中是否存在任何字段验证错误的方法。如果在模型发布到控制器方法之前,您不确定是什么原因导致模型无效,则可以检查
ModelState[“Property”]。Errors
属性,该属性应至少产生一个表单验证错误


编辑:使用@ChrisPratt的正确字典语法进行更新

您的模型上有任何必需的属性吗?如果未输入任何必填字段,则“模型”状态将无效。已输入所有必需属性,但“我的模型”状态仍然无效!请看我的回答,可能您的视图绑定到int或datetime,这是不可为null的,这也会导致ModelState无效。ModelState.Errors不存在!有:SerializeErrors和AddModelError,这是allIt的
ModelState[“Property”]。Errors
。换句话说,
ModelState
是一种字典。模型上发布的任何属性都将获得密钥。您必须在适当的属性上索引字典,才能查看该属性的错误。如果您只是想找出发生了什么错误,请进行调试,并在post操作中的某个位置设置断点。然后,逐键检查
ModelState
,查看每一个上的
错误集。谢谢,但仍然很模糊!例如,当我更改模型中的某些内容时,我需要将字符串转换为十进制,然后添加到数据库中。。modelstate.isvalid检查传入参数的模型,而不是我更新后的状态?Luke,你能解释一下为什么不再需要在ASP.NET Core 3.0中调用
modelstate.isvalid
?模型验证似乎是自动进行的,甚至在一些旧项目中,如ASP.NET Core 2.2等。非常感谢。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "EncaissementID,libelle,DateEncaissement,Montant,ProjetID,Description")] Encaissement encaissement) {

  // Perform validation
  if (!encaissement.DateEncaissement.HasValue)
  {
      this.ModelState.AddModelError("DateEncaissement", "The DateEncaissement must be set");
  }

  encaissement.Montant = Convert.ToDecimal(encaissement.Montant);

  ViewBag.montant = encaissement.Montant;

  if (ModelState.IsValid) {

    db.Encaissements.Add(encaissement);
    db.SaveChanges();
    return RedirectToAction("Index", "Encaissement");

  };

  ViewBag.ProjetID = new SelectList(db.Projets, "ProjetId", "nomP");

  return View(encaissement);
}