-4

Using Chrome PostMan, I noticed that if I post to an action method without passing any form parameters the ModelState.IsValid returns true even if I have [Required] validation attribute set on the model properties.

The weird thing is that the Model passed as a parameter has a value of null even though IsValid is true.

Is there a way to intercept the Model from OnActionExecuting to check if the Model is null and handle the situation appropriately or is there a better way to ensure IsValid returns false in this case?

Nikolay Kostov
  • 16,433
  • 23
  • 85
  • 123
user1790300
  • 2,143
  • 10
  • 54
  • 123
  • Can you provide your model and API code? If you have an `RequiredAttribute` and the value is `null`, validation should return `false`. Unless it is a non-nullable data type. This would cause it to default to a value, eg `int` defaults to `0` so it is technically valid data. See [fiddle](https://dotnetfiddle.net/JCbt9v) – Justin Jan 21 '15 at 15:51
  • 4
    Question itself and @Doug Dawson answer are full duplicates of http://stackoverflow.com/questions/17923622/modelstate-isvalid-even-when-it-should-not-be – Sergio Jan 23 '15 at 08:58

2 Answers2

1

Without your model data it will be impossible to truly help you.

However, your issue stems from the following:

  • ModelState.IsValid : When this is invoked, it will perform the following in essence: Values.All(m => m.Errors.Count == 0). Since the collection is empty, it will still validate as true. Since the collection is absent of errors.

To properly account for the information, you'll need to do the following:

// If Invalid
if(model == null && !ModelState.IsValid)
     return View("Error");

// If Vaild
if(model != null && ModelState.IsValid)
     return View("Valid");

The ModelState.IsValid represents the state of an attempt to bind a posted form to an action method, which includes the validation information. Another potential approach would be to do a Count on the KeyValuePair within the Dictionary.

if(ModelState.Count != 0)
     return View("Valid");

Another suggestion, hopefully this clarifies. The IsValid will trigger its count based on potential errors. If non exist within the Collection it will always return true.

Documentation:

Community
  • 1
  • 1
Greg
  • 11,302
  • 2
  • 48
  • 79
0

Edit: The closest I could find to "official" insight into this was a post at ASP.NET. The code shown in their example tests the model for null first and then checks if the model is valid in a separate step.

ASP.NET Model Binding

This is answered in the link below. Here's some of the content from that post:

The ModelState.IsValid internally checks the Values.All(modelState => modelState.Errors.Count == 0) expression.

Because there was no input the Values collection will be empty so ModelState.IsValid will be true.

So you need to explicitly handle this case with:

if (user != null && ModelState.IsValid)
{

}

Source Post

Community
  • 1
  • 1
Doug Dawson
  • 1,254
  • 2
  • 21
  • 37