Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Model change in post action not visible in Html.TextBoxFor?

This must be something very obvious but for me it looks very strange. I have simple controller, model with one property, and view which displays value of property and renders editor for that property. When I click the button, form is posted and exclamation mark is appened to property. This exclamation mark is visible in my view but only in p tag, not in input tag rendered by Html.TextBoxFor().

Why Html.TextBoxFor() ignores that I updated my model in post action?

Is there any way to change this behavior of Html.TextBoxFor()?

View

@model ModelChangeInPostActionNotVisible.Models.IndexModel

@using (Html.BeginForm())
{
    <p>@Model.MyProperty</p>
    @Html.TextBoxFor(m => m.MyProperty)
    <input type="submit" />
}

Model

namespace ModelChangeInPostActionNotVisible.Models
{
    public class IndexModel
    {
        public string MyProperty { get; set; }
    }
}

Controller

namespace ModelChangeInPostActionNotVisible.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View(new IndexModel { MyProperty = "hi" });
        }

        [HttpPost]
        public ActionResult Index(IndexModel model)
        {
            model.MyProperty += "!";
            return View(model);
        }
    }
}

HTML after clicking on submit button

<form action="/" method="post">    <p>hi!</p>
<input id="MyProperty" name="MyProperty" type="text" value="hi" />    <input type="submit" />
</form>
like image 442
Pol Avatar asked Nov 19 '12 23:11

Pol


2 Answers

This is by design.

The helper methods are using the ModelState, thus if the response of your request is using the same Model, it will display the value that was posted.

This is to allow you to render the same view in the situation where the validation would have failed.

To make sure you display the new information add : ModelState.Clear(); before you return.

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

namespace ModelChangeInPostActionNotVisible.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View(new IndexModel { MyProperty = "hi" });
        }

        [HttpPost]
        public ActionResult Index(IndexModel model)
        {
            model.MyProperty += "!";
            ModelState.Clear();
            return View(model);
        }
    }
}
like image 123
Yan Brunet Avatar answered Oct 15 '22 04:10

Yan Brunet


Yan Brunet is absolutely correct that the variable needs to be removed from the ModelState in order to be modified in the controller. You don't have to clear the entire ModelState, though. You could do the following to remove just the variable to want to modify:

 ModelState.Remove("MyProperty");

This would be useful in case you wanted to retain other values which the user had entered.

like image 37
rarrarrarrr Avatar answered Oct 15 '22 03:10

rarrarrarrr