Search code examples
c#asp.net-core-mvc.net-5modelstate

ASP.Net Core: How do you get the key of an invalid ModelState value?


II have an "Edit" page in my .Net 5./ASP.Net MVC app. If ModelState.IsValid is "false", I want to check the individual errors before rejecting the entire page.

PROBLEM: How do I get the "name" of an invalid item in the ModelState list?

For example:

  • handler method: public async Task<IActionResult> OnPostAsync()

  • if (!ModelState.IsValid): "false"

    this.ModelState.Values[0]: SubKey={ID}, Key="ID", ValidationState=Invalid Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateEntry {Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary.ModelStateNode}

Code:

foreach (ModelStateEntry item in ModelState.Values)
{
    if (item.ValidationState == ModelValidationState.Invalid)
    {
        // I want to take some action if the invalid entry contains the string "ID"
        var name = item.Key;  // CS1061: 'ModelStateEntry 'does not contain a definition for 'Key'
        ...

QUESTION: how do I read the "Key" from each invalid ModelState "Values" item???


RESOLUTION

My basic problem was iterating through "ModelState.Values". Instead, I needed to iterate through "ModelState.Keys" in order to get all the required information.

SOLUTION 1)

foreach (KeyValuePair<string, ModelStateEntry> modelStateDD in ModelState) 
{
    string key = modelStateDD.Key;
    ModelStateEntry item = ModelState[key];
    if (item.ValidationState == ModelValidationState.Invalid) {
        // Take some action, depending on the key
        if (key.Contains("ID"))
           ...

SOLUTION 2)

var errors = ModelState
               .Where(x => x.Value.Errors.Count > 0)
               .Select(x => new { x.Key, x.Value.Errors })
               .ToList();
foreach (var error in errors) {
    if (error.Key.Contains("ID"))
       continue;
    else if (error.Key.Contains("Foo"))
      ...

Many thanks to devlin carnate for pointing me in the right direction, and to PippoZucca for a great solution!


Solution

  • While debugging, you can type this:

    ModelState.Where(
      x => x.Value.Errors.Count > 0
    ).Select(
      x => new { x.Key, x.Value.Errors }
    )
    

    into your Watch window. This will collect all Keys generating error together with the error descritti in.