ASP.NET MVC and ViewState ASP.NET MVC and ViewState ajax ajax

ASP.NET MVC and ViewState


The convention is already available without jumping through too many hoops. The trick is to wire up the TextBox values based off of the model you pass into the view.

[AcceptVerbs(HttpVerbs.Get)]   public ActionResult CreatePost(){  return View();}[AcceptVerbs(HttpVerbs.Post)]public ActionResult CreatePost(FormCollection formCollection){  try  {    // do your logic here    // maybe u want to stop and return the form    return View(formCollection);  }  catch   {    // this will pass the collection back to the ViewEngine    return View(formCollection);  }}

What happens next is the ViewEngine takes the formCollection and matches the keys within the collection with the ID names/values you have in your view, using the Html helpers. For example:

<div id="content">  <% using (Html.BeginForm()) { %>  Enter the Post Title: <%= Html.TextBox("Title", Model["Title"], 50) %><br />  Enter the Post Body: <%= Html.TextArea("Body", Model["Body"]) %><br />  <%= Html.SubmitButton() %>  <% } %></div>

Notice the textbox and textarea has the IDs of Title and Body? Now, notice how I am setting the values from the View's Model object? Since you passed in a FormCollection (and you should set the view to be strongly typed with a FormCollection), you can now access it. Or, without strongly-typing, you can simply use ViewData["Title"] (I think).

POOF Your magical ViewState. This concept is called convention over configuration.

Now, the above code is in its simplest, rawest form using FormCollection. Things get interesting when you start using ViewModels, instead of the FormCollection. You can start to add your own validation of your Models/ViewModels and have the controller bubble up the custom validation errors automatically. That's an answer for another day though.

I would suggest using a PostFormViewModel instead of the Post object, but to each-his-own. Either way, by requiring an object on the action method, you now get an IsValid() method you can call.

[AcceptVerbs(HttpVerbs.Post)]public ActionResult CreatePost(Post post){  // errors should already be in the collection here  if (false == ModelState.IsValid())    return View(post);  try  {    // do your logic here    // maybe u want to stop and return the form    return View(post);  }  catch   {    // this will pass the collection back to the ViewEngine    return View(post);  }}

And your Strongly-Typed view would need to be tweaked:

<div id="content">  <% using (Html.BeginForm()) { %>  Enter the Post Title: <%= Html.TextBox("Title", Model.Title, 50) %><br />  Enter the Post Body: <%= Html.TextArea("Body", Model.Body) %><br />  <%= Html.SubmitButton() %>  <% } %></div>

You can take it a step further and display the errors as well in the view, directly from the ModelState that you set in the controller.

<div id="content">  <%= Html.ValidationSummary() %>  <% using (Html.BeginForm()) { %>  Enter the Post Title:     <%= Html.TextBox("Title", Model.Title, 50) %>    <%= Html.ValidationMessage("Title") %><br />  Enter the Post Body:     <%= Html.TextArea("Body", Model.Body) %>    <%= Html.ValidationMessage("Body") %><br />  <%= Html.SubmitButton() %>  <% } %></div>

What is interesting with this approach is that you will notice I am not setting the validation summary, nor the individual validation messages in the View. I like to practice DDD concepts, which means my validation messages (and summaries) are controlled in my domain and get passed up in the form of a collection. Then, I loop throught he collection (if any errors exist) and add them to the current ModelState.AddErrors collection. The rest is automatic when you return View(post).

Lots of lots of convention is out. A few books I highly recommend that cover these patterns in much more detail are:

And in that order the first covers the raw nuts and bolts of the entire MVC framework. The latter covers advanced techniques outside of the Microsoft official relm, with several external tools to make your life much easier (Castle Windsor, Moq, etc).


The View is supposed to be dumb in the MVC pattern, just displaying what the Controller gives it (obviously we do often end up with some logic there but the premise is for it not to be) as a result, controls aren't responsible for their state, it'll come from the controller every time.

I can't recommend Steven Sanderson's book Pro ASP.NET MVC by Apress enough for getting to grips with this pattern and this implementation of it.


In Web Forms, control values are maintained in the viewstate so you (theoretically) don't need to reinitialize and such with each postback. The values are (again theoretically) maintained by the framework.

In ASP.NET MVC, if you follow the paradigm, you don't need to maintain state on form elements. The form element values are available on post where your controller can act on them (validation, database updates, etc.). For any form elements that are displayed once the post is processed, you (the developer) are responsible for initializing them - the framework doesn't automatically do that for you.

That said, I have read about a mechanism called TempData that allows your controller to pass data to another controller following a redirect. It is actually a session variable (or cookie if you configure it as such) but it is automatically cleaned up after the next request.