What does ModelState.IsValid do?

ModelState.IsValid indicates if it was possible to bind the incoming values from the request to the model correctly and whether any explicitly specified validation rules were broken during the model binding process.

In your example, the model that is being bound is of class type Encaissement. Validation rules are those specified on the model by the use of attributes, logic and errors added within the IValidatableObject's Validate() method - or simply within the code of the action method.

The IsValid property will be true if the values were able to bind correctly to the model AND no validation rules were broken in the process.

Here's an example of how a validation attribute and IValidatableObject might be implemented on your model class:

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

Here's an example of how the same validation rule may be applied within the action method of your example:

[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);
}

It's worth bearing in mind that the value types of the properties of your model will also be validated. For example, you can't assign a string value to an int property. If you do, it won't be bound and the error will be added to your ModelState too.

In your example, the EncaissementID value could not have a value of "Hello" posted to it, this would cause a model validation error to be added and IsValid will be false.

It is for any of the above reasons (and possibly more) that the IsValid bool value of the model state will be false.


You can find a great write-up on ModelState and its uses here.

Specifically, the IsValid property is a quick way to check if there are any field validation errors in ModelState.Errors. If you're not sure what's causing your Model to be invalid by the time it POST's to your controller method, you can inspect the ModelState["Property"].Errors property, which should yield at least one form validation error.

Edit: Updated with proper dictionary syntax from @ChrisPratt


ModelState.IsValid will basically tell you if there is any issues with your data posted to the server, based on the data annotations added to the properties of your model.

If, for instance, you have a [Required(ErrorMessage = "Please fill")], and that property is empty when you post your form to the server, ModelState will be invalid.

The ModelBinder also checks some basic stuff for you. If, for instance, you have a BirthDate datepicker, and the property that this picker is binding to, is not a nullable DateTime type, your ModelState will also be invalid if you have left the date empty.

Here, and here are some useful posts to read.

Tags:

C#

Asp.Net Mvc