How do you get a list of all ModelState error messages? I found this code to get all the keys: ( Returning a list of keys with ModelState errors)
var errorK
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()
);
Variation with return type instead of returning IEnumerable
public static class ModelStateHelper
{
public static IEnumerable<KeyValuePair<string, string[]>> 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;
}
}
There are lots of different ways to do this that all work. Here is now I do it...
if (ModelState.IsValid)
{
return Json("Success");
}
else
{
return Json(ModelState.Values.SelectMany(x => x.Errors));
}
Take a look at System.Web.Http.Results.OkNegotiatedContentResult.
It converts whatever you throw into it to JSON.
So I did this
var errorList = ModelState.ToDictionary(kvp => kvp.Key.Replace("model.", ""), kvp => kvp.Value.Errors[0].ErrorMessage);
return Ok(errorList);
This resulted in:
{
"Email":"The Email field is not a valid e-mail address."
}
I am yet to check what happens when there is more than one error for each field but the point is the OkNegoriatedContentResult is brilliant!
Got the linq/lambda idea from @SLaks
Why not return the original ModelState
object to the client, and then use jQuery to read the values. To me it looks much simpler, and uses the common data structure (.net's ModelState
)
to return the ModelState
as Json, simply pass it to Json class constructor (works with ANY object)
C#:
return Json(ModelState);
js:
var message = "";
if (e.response.length > 0) {
$.each(e.response, function(i, fieldItem) {
$.each(fieldItem.Value.Errors, function(j, errItem) {
message += errItem.ErrorMessage;
});
message += "\n";
});
alert(message);
}
List<ErrorList> Errors = new List<ErrorList>();
//test errors.
var modelStateErrors = this.ModelState.Keys.SelectMany(key => this.ModelState[key].Errors);
foreach (var x in modelStateErrors)
{
var errorInfo = new ErrorList()
{
ErrorMessage = x.ErrorMessage
};
Errors.Add(errorInfo);
}
if you use jsonresult then return
return Json(Errors);
or you can simply return the modelStateErrors, I havent tried it. What I did is assign the Errors collection to my ViewModel and then loop it..In this case I can return my Errors via json. I have a class/model, I wanted to get the source/key but I'm still trying to figure it out.
public class ErrorList
{
public string ErrorMessage;
}