ASP.NET MVC How to convert ModelState errors to json
Here is the full implementation with all the pieces put together:
First create an extension method:
public static class ModelStateHelper
{
public static IEnumerable Errors(this ModelStateDictionary modelState)
{
if (!modelState.IsValid)
{
return modelState.ToDictionary(kvp => kvp.Key,
kvp => kvp.Value.Errors
.Select(e => e.ErrorMessage).ToArray())
.Where(m => m.Value.Any());
}
return null;
}
}
Then call that extension method and return the errors from the controller action (if any) as json:
if (!ModelState.IsValid)
{
return Json(new { Errors = ModelState.Errors() }, JsonRequestBehavior.AllowGet);
}
And then finally, show those errors on the clientside (in jquery.validation style, but can be easily changed to any other style)
function DisplayErrors(errors) {
for (var i = 0; i < errors.length; i++) {
$("<label for='" + errors[i].Key + "' class='error'></label>")
.html(errors[i].Value[0]).appendTo($("input#" + errors[i].Key).parent());
}
}
I like to use Hashtable
here, so that I get JSON object with properties as keys and errors as value in form of string array.
var errors = new Hashtable();
foreach (var pair in ModelState)
{
if (pair.Value.Errors.Count > 0)
{
errors[pair.Key] = pair.Value.Errors.Select(error => error.ErrorMessage).ToList();
}
}
return Json(new { success = false, errors });
This way you get following response:
{
"success":false,
"errors":{
"Phone":[
"The Phone field is required."
]
}
}
You can put anything you want to inside the select
clause:
var errorList = (from item in ModelState
where item.Value.Errors.Any()
select item.Value.Errors[0].ErrorMessage).ToList();
EDIT: You can extract multiple errors into separate list items by adding a from
clause, like this:
var errorList = (from item in ModelState.Values
from error in item.Errors
select error.ErrorMessage).ToList();
Or:
var errorList = ModelState.Values.SelectMany(m => m.Errors)
.Select(e => e.ErrorMessage)
.ToList();
2nd EDIT:
You're looking for a Dictionary<string, string[]>
:
var errorList = ModelState.ToDictionary(
kvp => kvp.Key,
kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray()
);