Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Textbox reverts to old value while Modelstate is valid on postback

Maybe I'm missing something but when I have a form that posts back to the same action, the textbox value reverts to the old value. The following example should increment the value in the textbox on each POST. This does not happen, the value on the model is incremented and the model is valid.

IF however I clear the modelstate in the HttpPost Action (the comment in the code), everything works as expected.

Am I missing something?

Here's the code:

Model:

public class MyModel
{
    public int MyData { get; set; }
}

View:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage<MvcApplication1.Models.MyModel>" %>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% using (Html.BeginForm()) {%>
    <%: Html.TextBoxFor(m => m.MyData)%>   (<%: Model.MyData%>)
                  <%: Html.ValidationMessageFor(m => m.MyData) %> <br />
    State :<%: ViewData["State"] %> <br />
    <input type="submit" />
<% } %>
</asp:Content>

Controller:

public class HomeController : Controller
{
    [HttpGet]
    public ActionResult Index()
    {
        return View(new MyModel { MyData = 0 });
    }

    [HttpPost]
    public ActionResult Index(MyModel myModel)
    {
        // ModelState.Clear();
        ViewData["State"] = "invalid";
        if (ModelState.IsValid)
            ViewData["State"] = "Valid";

        var model = new MyModel { MyData = myModel.MyData + 1 };
        return View(model);
    }

}
like image 462
John Landheer Avatar asked Jan 06 '11 13:01

John Landheer


2 Answers

I just found an answer to this online.

The trick is to clear the ModelState before returning the Model

[HttpPost]
public ActionResult Index(MyModel myModel)
{
    // ModelState.Clear();
    ViewData["State"] = "invalid";
    if (ModelState.IsValid)
        ViewData["State"] = "Valid";

    var model = new MyModel { MyData = myModel.MyData + 1 };

    ModelState.Clear();

    return View(model);
}

For more detail read these 2 articles

http://forums.asp.net/p/1527149/3687407.aspx

Asp.net MVC ModelState.Clear

like image 85
Mark Avatar answered Oct 21 '22 12:10

Mark


You should either use the Post-Redirect-Get pattern or not use the Html Helpers.

Reference: http://blogs.msdn.com/b/simonince/archive/2010/05/05/asp-net-mvc-s-html-helpers-render-the-wrong-value.aspx

Basically MVC expects any redisplay from a post to be a validation error, and re-uses the posted data (view ModelState) for redisplay in preference to model data. The guidance is to not use ModelState.Clear().

like image 40
Tim Abell Avatar answered Oct 21 '22 13:10

Tim Abell