MVC ModelState.Clear. Is it a Bug?

 

Introduction

So I know many of you have most likely had to create a form in MVC right? Right! Ok, so how many of you on submission want to send the user back to the same form and then want to clear the data out and display a message saying everything is right with the world and “please may I have another”. Probably not everyone, but probably anyone who found this blog :).

Scenario Code

Ok. So we have a View Model that looks like this:

public class EventModel
{
public Guid EventID { get; set; }
[Required(ErrorMessage= "Please enter an event name")]
public string EventName { get; set; }

[Required(ErrorMessage = "Please enter an event date")]
public DateTime EventDate { get; set; }
}

 

 

 

 

You’ll notice that EventID has no required stuff right? Remember that for later. now the below is the relevant code in the controller. The big thing of interest what gets passed to the View upon completion. See the bold underline portion of the code below.

[HttpPost]
[ValidateInput(false)]
public ActionResult AddEvent(EventModel formInput)
{
if (!EventFormIsValid(formInput, ModelState))
return View(formInput);

ViewData["Message"] = "";

EventModel model = CallService.AddEvent(formInput);

if (model != null && model.EventID != Guid.Empty)
{
ViewData["Message"] = "New Event Created";


EventModel newModel = new EventModel();
return View(newModel);

 

}


else
{
ViewData["Message"] = "New Event Failed to be created. If this problem persists, please contact your administrator";
return View(formInput);
}

 

That should give us a nice fresh model without the headache of having to do stuff in JS right? Well, not exactly. I left out an important piece though, so before I explain further, lets step back and look at my EventFormIsValid methods. This is a static method in a class called CallService. As you can see below, everything is nice and tidy. I’m passing in the ModelState Dictionary and the model for validating.

public static bool EventFormIsValid(ColdCallEventModel model, ModelStateDictionary modelState)
{
bool IsValid = false;

modelState.Remove("EventID");

if (modelState.IsValid)
IsValid = true;


return IsValid;
}

 

Now you may notice, that I am using the Remove property to remove the EventID from being being an error because for a new event, we don’t know the ID yet, but will use it later for editing the event ( Not relevant to this tutorial). So it returns valid and everything is right with the world right? Wrong. Apparently, the ModelState somewhere deep down inside still thinks it’s invalid, so it caches your old model and that’s what gets placed back in the form. This is By Design! It is used to make it easier to show the user on failed validation what went wrong and how to fix it.

 

Ok Gregg, So what do we do about it?

I’m sooo glad you asked :). We use ModelState.Clear(). So given the code before inside the Controller, here is the revised code:

 

[HttpPost]
[ValidateInput(false)]
public ActionResult AddEvent(EventModel formInput)
{
if (!EventFormIsValid(formInput, ModelState))
return View(formInput);

ViewData["Message"] = "";

EventModel model = CallService.AddEvent(formInput);

if (model != null && model.EventID != Guid.Empty)
{
ViewData["Message"] = "New Event Created";

 

ModelState.Clear();
EventModel newModel = new EventModel();
return View(newModel);

}


else
{
ViewData["Message"] = "New Event Failed to be created. If this problem persists, please contact your administrator";
return View(formInput);
}

 

Happy Coding 🙂

Advertisements

About Gregg Coleman

I am Senior-level Software Engineer working primarily these days with .NET. I have a good working knowledge of ASP.NET MVC, Web Forms, WCF web services and Windows Services. I spend much of my time in the Web Services (SOAP and REST) world in my current job designing and implementing various SOA architectures. I have been in the software engineering industry for about 6 years now and will not now nor ever consider myself an "expert" in programming because there is always so much to learn. My favorite thing about designing software is there are always new emerging technologies and something to learn every day! My current job has me spending much of my job on the bleeding edge of technologies and changing gears all the time, so I'm never bored and always challenged. On my spare time I enjoy weight training, reading and venturing to new places near by. Of course programing and learning new technologies are another hobby of mine.
This entry was posted in ASP.NET, C#, Computer Technology, MVC, Performance and tagged , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s