Reputation: 29720
I have an ASP.NET MVC application that is meant to be user friendly and out of the box MVC does not offer ViewState. My problem is that if the user fails server validation then I don't want them to have to enter all the values again.
How do I solve this problem in ASP.NET MVC?
Upvotes: 3
Views: 4020
Reputation: 2670
what all the fuss is about not maintaining state in a web application?
This is a complicated area. For instance, one disadvantage of using session to manage state is that if it is an RW session, only one thread at a time can interact with it. This becomes a problem if you have multiple threads in-flight for the same session (for instance, for multiple ajax calls from the same page being executed in parallel). Having session enabled means that these threads get blocked when interacting with the RW session and thus each subsequent thread takes longer and longer to execute.
Also, for web applications that are meant to be failure tolerant, if you are using multiple nodes as a farm, you then have to use a shared session state backing provider (to SQL server or a distributed cache) to ensure that whichever server the user ends up hitting that they seem the same state. This carries a performance penalty.
But to be honest if the user fails server validation then I dont want them to have to enter all the values again
For this issue, to avoid a full postback and ensure that the user's volatile data entered in the page is kept even if there is a validation issue you should try and implement client side validation. This is not my area of expertise but you should look at Unobtrusive Client Side Validation. It is a bit of work to implement it but worth it for performance and usability reasons.
As regards the merits / demerits of viewstate in general, I think the reason conventional wisdom is moving away from this is that (as I'm sure you're aware), viewstate carried a lot of potential pitfalls including potentially unnecessarily large states being transferred to and from the browser (and having to be de-serialized on the server side) and also resulting in impure html being rendered at the client. IMHO the best thing about MVC is the cleanness of the HTML that gets rendered.
For a simple, single, monolithic web app that does not have to be super failover tolerant I don't see an issue with using ASP.NET + Viewstate for session management. It all depends on what your site needs to achieve. I'm sure others will have their thoughts. Hope this is useful for you!
Upvotes: 0
Reputation: 1038930
But to be honest if the user fails server validation then I dont want them to have to enter all the values again. I dont really understand what the MVC solution is to this useability problem?
The pattern is pretty simple actually. You design a view model:
public class MyViewModel
{
[Required]
public string Foo { get; set; }
public string Bar { get; set; }
public int Baz { get; set; }
}
then a controller:
public class HomeController: Controller
{
public ActionResult Index()
{
return View(new MyViewModel());
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
if (!ModelState.IsValid)
{
// validation failed => redisplay the view so that
// the user can fix his errors
return View(model);
}
// TODO: A this stage the model passed validation =>
// do some processing here and redirect
return RedirectToAction("Success");
}
}
and finally a corresponding view:
@model MyViewModel
@Html.ValidationSummary(false)
@using (Html.BeginForm())
{
<div>
@Html.LabelFor(x => x.Foo)
@Html.EditorFor(x => x.Foo)
</div>
<div>
@Html.LabelFor(x => x.Bar)
@Html.EditorFor(x => x.Bar)
</div>
<div>
@Html.LabelFor(x => x.Baz)
@Html.EditorFor(x => x.Baz)
</div>
<p><button type="submit">OK</button></p>
}
Now when a user navigates to /home/index
he is presented with a form to fill in which he enters some information in the corresponding input fields and submits the form. The default model binder kicks in and binds the view model from the request values in the corresponding POST action. If validation fails, the modelstate is marked as invalid and you can now redisplay the same view. Since all the information has been posted in the modelstate the HTML helpers that were used to generate the input fields will be able to retrieve the values and preserve them during the postback phase.
Upvotes: 5