Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Html.TextBox uses Request.Params instead of Model?

I have a simple test application:

Model:

public class Counter
{
    public int Count { get; set; }

    public Counter()
    {
        Count = 4;
    }
}

Controller:

public class TestController : Controller
{
    public ActionResult Increment(Counter counter)
    {
        counter.Count++;
        return View(counter);
    }
}

View:

<form action="/test/increment" method="post">
    <input type="text" name="Count" value="<%= Model.Count %>" />
    <input type="submit" value="Submit" /> 
</form>

Clicking Submit I get such values:

5, 6, 7, 8, ...

With Html.TextBox I expected the same behaviour

<form action="/test/increment" method="post">
    <%= Html.TextBox("Count") %>
    <input type="submit" value="Submit" /> 
</form>

but actually got

5, 5, 5, 5.

It seems Html.TextBox uses Request.Params instead of Model?

like image 785
alex2k8 Avatar asked Jun 04 '09 21:06

alex2k8


1 Answers

Html.TextBox() uses internally ViewData.Eval() method which first attempts to retrieve a value from the dictionary ViewData.ModelState and next to retrieve the value from a property of the ViewData.Model. This is done to allow restoring entered values after invalid form submit.

Removing Count value from ViewData.ModelState dictionary helps:

public ActionResult Increment(Counter counter)
{
    counter.Count++;
    ViewData.ModelState.Remove("Count");
    return View(counter);
}

Another solution is to make two different controller methods for GET and POST operations:

public ActionResult Increment(int? count)
{
    Counter counter = new Counter();

    if (count != null)
        counter.Count = count.Value;

    return View("Increment", counter);
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Increment(Counter counter)
{
    counter.Count++;

    return RedirectToAction("Increment", counter);
}

Counter object could also be passed via TempData dictionary.

You may also be interested in the article Repopulate Form Fields with ViewData.Eval() by Stephen Walther.

like image 149
Alexander Prokofyev Avatar answered Sep 21 '22 06:09

Alexander Prokofyev