Explain Codes LogoExplain Codes Logo

How do I get the collection of Model State Errors in ASP.NET MVC?

javascript
error-handling
model-state
asp-net-mvc
Nikita BarsukovbyNikita Barsukov·Oct 14, 2024
TLDR

To retrieve Model State Errors in ASP.NET MVC, run a concise LINQ query on the ModelState:

var errorList = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage).ToList();

This approach extracts all the error messages into a single List<string>, which can then be tagged for display or logging.

Digging deeper into error-management

Validating ModelState

In an ASP.NET MVC application, validation errors that occur during model binding get conveniently scooped up by the ModelState. By checking ModelState.IsValid, we ensure no actions are performed on invalid data:

if (!ModelState.IsValid) { // Because garbage in, garbage out! }

Pinning down specific errors

To identify errors without having to execute an action, use:

bool hasErrors = ViewData.ModelState.Values.Any(x => x.Errors.Count >= 1);

For a granular view of errors pertaining to individual properties, thumb through the errors a bit:

foreach (var stateValue in ViewData.ModelState) { foreach (var error in stateValue.Value.Errors) { // Here be dragons (i.e., errors)! } }

Crafty error formatting and rendering

For a custom error summary view, consider formatting the error messages into one tidy, readable string:

var singleErrorMessage = string.Join("; ", ModelState.Values .SelectMany(e => e.Errors) .Select(e => e.ErrorMessage));

LINQ to wrangle errors

LINQ's SelectMany comes in handy to flatten nested collections while ModelState.Keys allows you to sweep through relevant properties:

var modelStateErrors = ModelState .Where(kvp => kvp.Value.Errors.Count > 0) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Errors .Select(e => e.ErrorMessage) .ToArray()); // Because dictionaries don't play "Hide and Seek"

Polishing error display and enhancing controls

User experience gets a boost by marking out fields with errors. This can be established by pairing errors with relevant controls like so:

@Html.TextBoxFor(m => m.Name, new { @class = ViewData.ModelState["Name"].Errors.Any() ? "input-validation-error" : "" }) @Html.ValidationMessageFor(m => m.Name) // Let's play "Spot the Error!"

Once errors are caught, help users fix their input:

  • Traverse through ModelState to list errors next to form fields.
  • Bring errors into sharp relief with conditional CSS classes.
  • Deliver quick, realtime feedback using data annotations on your models.

Accessible error handling

Strive to make your errors accessible to every user, including those using screen readers:

  • Attribute aria-invalid="true" to inputs with errors for better accessibility.
  • Use aria-live regions for prompt feedback to screen reader users.

ModelState error handling best practices

Consider adopting these best practices:

  • Log ModelState errors for auditing and troubleshooting.
  • Avoid tech gibberish in error messages - be clear and actionable.
  • Present errors without overwhelming users - small acts of kindness, like tooltips or inline messages, go a long way.