21

How do I figure out which of the keys in ModelState that contains an error when ModelState.IsValid is false? Usually I would just hover the mouse thru the ModelState.Values list checking item by item for error count > 0. But now I'm working on a view that has some lists of complex objects, totalling 252 ModelState items(each item of each object of each list has an entry on ModelState.Keys).

So, is there an easier way to point out the error source?

tereško
  • 58,060
  • 25
  • 98
  • 150
leobelones
  • 578
  • 1
  • 8
  • 24

6 Answers6

36

You can check the ViewData.ModelState.Values collection and see what are the Errors.

[Httpost]
public ActionResult Create(User model)
{
   if(ModelState.IsValid)
   {
     //Save and redirect
   }
   else
   {
     foreach (var modelStateVal in ViewData.ModelState.Values)
     {
       foreach (var error in modelStateVal.Errors)
       {               
          var errorMessage = error.ErrorMessage;
          var exception = error.Exception;
          // You may log the errors if you want
       }
     }
   }         
   return View(model);
 }
}

If you really want the Keys(the property name), You can iterate through the ModelState.Keys

foreach (var modelStateKey in ViewData.ModelState.Keys)
{
    var modelStateVal = ViewData.ModelState[modelStateKey];
    foreach (var error in modelStateVal.Errors)
    {
        var key = modelStateKey; 
        var errorMessage = error.ErrorMessage;
        var exception = error.Exception;
        // You may log the errors if you want
    }
}
Shyju
  • 214,206
  • 104
  • 411
  • 497
  • This helped me find the problem. Wasn't exactly what I was looking for, but solved anyways... thanks! – leobelones Mar 08 '13 at 15:08
  • This works, but doesn't answer the question; how to find out which KEY of the ModelState has an error. In this solution, we get the error, but not the key this error belongs to. How do we achieve that? – Jay Regal Jul 06 '16 at 09:59
  • 1
    @RensdeNobel I updated the answer to include that as well. – Shyju Jul 06 '16 at 14:48
  • The `Key` seems to include some GUID. Don't forget to sanitize it. – Azimuth Nov 29 '16 at 11:30
  • It is baffling to me why the validation error collection is implemented this way where you cannot simply select the errors based on key (or part of the key) e.g. ViewData.ModelState.Values.Where(w => w.Key.StartsWith("something")). I guess they have their reasons. – mattpm Aug 08 '22 at 01:56
2
ModelState.Values.SelectMany(v => v.Errors);

is considered cleaner.

IncaKola
  • 69
  • 1
1

where modelState is a ModelStateDictionary object

foreach (var keyModelStatePair in modelState)
    {
        var key = keyModelStatePair.Key;
        var errors = keyModelStatePair.Value.Errors;
        if (errors != null && errors.Count > 0)
        {
            var errorMessages = errors.Select(error =>
            {
                return error.ErrorMessage;
            }).ToArray();

            // do something with your keys and errorMessages here
        }
    }
cblanto7
  • 168
  • 1
  • 3
  • 12
0

I had the same problem for a long time and finally I found it. In my case, it was the Id field :)

Just place a breakpoint and check your ModelState in runtime and go to this section :

ModelState -> Root -> Children

and you will see all valid and invalid Keys

enter image description here

Mohammad Taheri
  • 348
  • 2
  • 9
0

Did some modification to the solution provided by @cblanto7.

    _logger.LogInformation("ModelState is not valid: In yourmodelName/yourActionName.");
    foreach (var keyModelStatePair in ModelState)
    {
        var errors = keyModelStatePair.Value.Errors;
        if (errors != null && errors.Count > 0)
        {
            var key = keyModelStatePair.Key;
            var errorMessageArray = errors.Select(error =>
            {
                return error.ErrorMessage;
            }).ToArray();

            var errorMessages = string.Join(", ", errorMessageArray); 
            _logger.LogInformation($"ModelState is not valid:{key} has {errorMessages}");
            
        }
    }
0

following method Gives Dictionary Response of errors can Return it In Badrequest Based on th functionality.

        var ErrorDictionary=ModelState
                .Where(x => x.Value.Errors.Count > 0)
                .ToList()
                .ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Errors.Select(x => x.ErrorMessage).ToList());
Upender Reddy
  • 568
  • 3
  • 8