How to Get the Collection of Model State Errors in ASP.NET MVC

How to get all Errors from ASP.Net MVC modelState?

foreach (ModelState modelState in ViewData.ModelState.Values) {
foreach (ModelError error in modelState.Errors) {
DoSomethingWith(error);
}
}

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

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

<% ViewData.ModelState.IsValid %>

or

<% ViewData.ModelState.Values.Any(x => x.Errors.Count >= 1) %>

and for a specific property...

<% ViewData.ModelState["Property"].Errors %> // Note this returns a collection

How do you get errors in the ModelState, for a particular property?

Assuming you want the error(s) for proeprty Name

string propertyName = "Name";

To get the first error (which is what will be displayed when using @Html.ValidationSummary(), you can use

string error = ViewData.ModelState.Keys.Where(k => k == propertyName)
.Select(k => ModelState[k].Errors[0].ErrorMessage).First();

or to get all errors for a property

IEnumerable<string> errors = ModelState.Keys.Where(k => k == propertyName)
.Select(k => ModelState[k].Errors).First().Select(e => e.ErrorMessage);

and use your foreach as noted in the question

Display Model state Errors in View?

You can Access ModelState class in view with the key :

Controller : ModelState.AddModelError("ProductSRDate", "Date must be current date or in the past.");

View : @Html.ValidationMessage("ProductSRDate")

But you're code logical error because you add an error to your ModelState if IsValid.

if (!ModelState.IsValid || updatedProduct.ProductSRDate.Value > DateTime.Now)
{
if (updatedProduct.ProductSRDate.Value > DateTime.Now)
{
ModelState.AddModelError("ProductSRDate", " Date must be current date or in the past.");
}
//return BadRequest(ModelState.Values.SelectMany(v => v.Errors).Select(error => error.ErrorMessage));
return View(editMode); // You should return a view and handle Invalid ModelState in view.
}
else
{
var PrjEditMode = await ProductService.GetProductsbyId(id);
var editMode = Mapper.Map<ProductDetails>(PrjEditMode);
return View(editMode);
}

How to check if ModelState contains errors which are not properties

Ok i think i have working solution

@if (ViewData.ModelState.Keys.Contains(string.Empty))
{
@Html.ValidationSummary(true)
}

Get all ModelState Errors on view

You can access it through ViewData.ModelState.
If you need more control with errors on your view you can use

ViewData.ModelState.IsValidField("name_of_input")

or get a list of inputs with errors like this:

var errors = ViewData.ModelState.Where(n => n.Value.Errors.Count > 0).ToList();

how to get ALL errors from viewdata.modelstate

I found out why this wasn't working for me. As usual it was me being silly. Because the model has multiple layers / levels to it, I.e. model.someobject.someotherobject.someproperty, when I called tryValidateModel it would validate the top level but not the inner layers.

The solution to this was to ensure they are all called:

            TryValidateModel(mp);
TryValidateModel(mp.ContactInformation.PrimarySiteAddress);
TryValidateModel(mp.ContactInformation.RegisteredOfficeAddress);

So my solution is to either create a method to call try validate on each object level or create a refelctive method to do it for me.

Get error message if ModelState.IsValid fails?

You can do this in your view without doing anything special in your action by using Html.ValidationSummary() to show all error messages, or Html.ValidationMessageFor() to show a message for a specific property of the model.

If you still need to see the errors from within your action or controller, see the ModelState.Errors property

Is there a way to clear modelstate errors on the client?

It makes no sense to attempt to attempt to clear ModelState errors from the client. ModelState is only set within the controller method (by the DefaultModelBinder) when you make a request to the method. In any case, your issues are not related to ModelState being valid or invalid in the controller method.

There are a number of changes you need to make to your code:

You should delete your EditorTemplate for decimal? It means that any property of that type is going to use that template. Instead replace your

@Html.EditorFor(m => Model.Options[i].Value, ...)

with

@(Html.Kendo().CurrencyTextBoxFor(m => m.Options[i].Value)....

in the main view.

If you really do want to use a template, then make it a named template (which is called using @Html.EditorFor(m => Model.Options[i].Value, "yourTemplateName"), but in any case, you need to remove the code relating to attemptedValue and modelStateForValue (including the if block) - the EditorFor() methods will always correctly use values from ModelState if they exist.

Next, your RequiredIfAttribute does not implement IClientValidatable so you will not get client side validation. You could use the foolproof library, or if you want to write your own, refer this answer for the full implementation of a RequiredIfAttribute, including the scripts for client side validation.

Next, you need to delete the IValidatableObject implementation (the Validate() method) from your model. That is just repeating the validation that the [RequiredIf] attribute is doing, and you should avoid mixing ValidationAttribute's with IValidatableObject (refer The Complete Guide To Validation In ASP.NET MVC 3 - Part 2 for more detailed information).

Finally, the Kendo().CurrencyTextBoxFor() method hides the input and renders its own html. By default, hidden inputs are not validated, so you need to reconfigure the validator. In the main view, add the following script (after the jquery-{version}.js, jquery.validate.js and jquery.validate.unobtrusive.js scripts

<script>
$.validator.setDefaults({
ignore: []
});
.... // other scripts as required
<script>

How to figure out which key of ModelState has error

You can check the ViewData.ModelState.Values collection and see what are the Errors.

[Httpost]
public ActionResult Create(User model)
{
if(ModelState.IsValid)
{
//Save and redirect
}
else
{
foreach (var modelStateVal in ViewData.ModelState.Values)
{
foreach (var error in modelStateVal.Errors)
{
var errorMessage = error.ErrorMessage;
var exception = error.Exception;
// You may log the errors if you want
}
}
}
return View(model);
}
}

If you really want the Keys(the property name), You can iterate through the ModelState.Keys

foreach (var modelStateKey in ViewData.ModelState.Keys)
{
var modelStateVal = ViewData.ModelState[modelStateKey];
foreach (var error in modelStateVal.Errors)
{
var key = modelStateKey;
var errorMessage = error.ErrorMessage;
var exception = error.Exception;
// You may log the errors if you want
}
}


Related Topics



Leave a reply



Submit