7

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!

FoggyDay
  • 11,962
  • 4
  • 34
  • 48
  • Does the selected answer in [this thread](https://stackoverflow.com/questions/1352948/how-to-get-all-errors-from-asp-net-mvc-modelstate) answer your question? (see the comments for that selected answer, too, because someone states how to get the "key") – devlin carnate Sep 13 '21 at 20:14
  • @devlin carnate: Thank you for your reply. I looked at the solutions in that link. Unfortunately, the only things they retrieve are the error messages. I want to know the name of the model object that caused the error. That's the part I haven't been able to figure out yet. – FoggyDay Sep 13 '21 at 20:21
  • Does this answer your question? [How to get all Errors from ASP.Net MVC modelState?](https://stackoverflow.com/questions/1352948/how-to-get-all-errors-from-asp-net-mvc-modelstate) – Serge Sep 13 '21 at 20:25
  • @FoggyDay : so you tried the solution in the comment? The comment posted by "viggity". It specifically states it shows the errors by key... – devlin carnate Sep 13 '21 at 20:42

1 Answers1

7

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.

PippoZucca
  • 141
  • 2
  • Brilliant - EXACTLY what I was looking for. It combines "Key" and "Error" in such a way that I can check each model error by field name. Perfect - thank you! – FoggyDay Sep 13 '21 at 20:48