Hi, I have a question about the ModelState in an ASP.NET MVC controller.
When the user selects a certain option from the view, the start date and end date for the "certification" will be set based on the other dates entered.
The problem with this is the certification dates come back as null and our CertificationMetaData class specifys the fields as [Required] so the ModelState is invalid as soon as the action loads.
Removing the ModelSate errors manually allows this to work but I was wondering if there is a better way to do this? Is there a way to refresh the ModelState? Should I make the fields not required? Or should I add a date value from the view with javascript?
public ActionResult Create(FormCollection fc, Certification certification, Absence absence)
{
if (certification.CertificationTypeID == 1)
{
certification.CertificationStartDate = absence.StartDate;
certification.CertificationEndDate = absence.StartDate.AddDays(7);
this.ModelState.Remove("CertificationStartDate");
this.ModelState.Remove("CertificationEndDate");
}
if (this.ModelState.IsValid)
{
// save
return RedirectToAction("Index");
}
return View();
}
Also as you can see I have hardcoded the ID value for the certification type. What is the best way to compare values with lookup table values? Is an enum the best way to go?
Thanks
AddModelError() method to add a validationerror to the ModelState. If you then check the IsValid property in the ModelState variable, it will say its not valid. If you call ModelState. Clear() and then check the IsValid property again it will be valid.
To clear the memory of the model state you need to use ModelState. Clear(). You could also remove only the desired field by using method of ModelState.
You can try calling the built in TryUpdateModel method which returns a boolean so you can check that value. UPDATE: Try using TryUpdateModel with exceptions. Use a formcollection instead of Comment into the Action.
The ModelState has two purposes: to store the value submitted to the server, and to store the validation errors associated with those values.
The following approach refreshes the model state and allows you to keep your model design consistent with [required] attributes etc.
In my case I want my model to have a required field that normal level users using an API can't change, so I've done this:
ModelState.Remove("ChangeDate");
ModelState.Add("ChangeDate", new ModelState());
ModelState.SetModelValue("ChangeDate", new ValueProviderResult(club.ChangeDate, DateTime.Now.ToString(), null));
That way you don't need to remove your required fields, and you also don't need to supply a date in javascript.
Obviously this is a personal thing, but I wouldn't remove the error messages.
If I was going for the simple solution then I would remove the [Required] attribute and add validation code to the controller to add the error if the dates were missing or set them to the alternate value if it was the correct type.
If I was going for the more complex solution I would put the validation at the Model level. Possibly a base class or and interface that the model must implement. A ValidationHelper class with a static Validate(IValidate object) method that will inspect the ValidationAttributes and calls a Validate method on the Model. It would then return a collection of ValidationErrors. Then a custom ModelBinder would be written that understands the Model validation and maps these to ModelState errors.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With