12

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);
    }

}
Neil Knight
  • 47,437
  • 25
  • 129
  • 188
John Landheer
  • 3,999
  • 4
  • 29
  • 53

2 Answers2

8

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

Community
  • 1
  • 1
Mark
  • 1,108
  • 10
  • 11
  • Thanks. I knew that clearing the ModelState would work, I just didn;t know why it had to be done for a valid model. The first link has some comments by Brad Wilson explaining that this is by design, the view will always use the ModelState if available, regardless of the model being valid or not.. A solution that also works is redirecting to an action instead of returning the view again (cause that will use the available ModelState). – John Landheer Jan 19 '11 at 10:36
  • Apparently you shouldn't clear the model state - see http://blogs.msdn.com/b/simonince/archive/2010/05/05/asp-net-mvc-s-html-helpers-render-the-wrong-value.aspx – Tim Abell Feb 17 '12 at 10:24
3

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().

Tim Abell
  • 11,186
  • 8
  • 79
  • 110