8

I'm just trying to get back into .NET MVC with the new release and I can't get my head round the way may view is binding to the DataModel.

I have a model with a property "first_name" and within an HTML form I have the following

<%= Html.TextBox("first_name", Model.first_name)%>
<%= Html.TextBoxFor(model => model.first_name) %> 
<input type="text" name="first_name" id="first_name" class="myLabel" 
       value="<%=Model.first_name %>" />

In an action on a controller if I set the first_name property on my model and do

mymodelObject.first_name = "Test";
return View(mymodelObject);

What is the reason only the third textbox picks up on this first_name value and the other two don't?

Edit:

I probably haven't explained this well enough, sorry. Imagine I have 2 controller methods -

public ActionResult Register()
{
    Registration model = new Registration();
    model.first_name = "test";
    return View(model);
}

With this one either binding works.

After this has been displayed I then click a button on the form and try and run this:

[HttpPost]
public ActionResult Register(Registration_ViewData model)
{
    model.first_name = "Steve";
    return View(model);
}

What I'm asking is why does the 3rd but not the first 2 bind to "Steve" as the new name.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
  • Are all three text boxes displayed but only the third has "Test" in? Or is it only the third text box displayed? I've just tried your code in a test app and all three work fine. What version of MVC 2 are you using? – lancscoder Feb 19 '10 at 16:15
  • Hi Simon, sorry - more background added its after an HttpPost that I can't seem to set the value, e.g. if I had a button on the form called "Click here if your name is Steve". then it fills the value of the third textbox and leaves the other two. Sorry bit of a beginner I'm sure I'm making this harder for everyone with my explanation. –  Feb 19 '10 at 16:20
  • This may have something to do with your ModelState because you post and return the same view but you don't actually use the form collection values to update the model. Check your ModelState keys and values to see if while rendering the page the second time, the value for the first two boxes is "test" or "Steve". – Chris F Feb 19 '10 at 16:24

3 Answers3

8

You need to clear your model state so your code would look something like:

[HttpPost]
public ActionResult Register(Registration model)
{
    ModelState.Clear();
    model.first_name = "Steve";
    return View(model);
}
lancscoder
  • 8,658
  • 8
  • 48
  • 68
5

Because HTML helpers read the value from the ModelState and not from the model. In order the change that behavior you'll need to work with the ModelState as well.
(see: Changing model’s properties on postback)

Community
  • 1
  • 1
Çağdaş Tekin
  • 16,592
  • 4
  • 49
  • 58
  • 2
    You're quite right, as is Chris in his comment above. The ModelState still had the contents that were posted back and the HTML Helper by default binds to that rather than the object I gave it. All it needs is ModelState.Clear(); Thanks everyone, some things look very complicated until they're explained to you! –  Feb 19 '10 at 16:40
  • @Doug, if I'm not mistaken `ModelState["first_name"].Value = new ValueProviderResult("Steve", "Steve", CultureInfo.CurrentCulture);` should also do the trick. In case you don't want to clear the whole dictionary. – Çağdaş Tekin Feb 19 '10 at 16:46
  • use `ModelState.Remove("FirstName");` instead of `ModelState["first_name"].Value = ... ` – S.Serpooshan Jan 28 '14 at 09:33
1

This should work for the first two:

<%= Html.TextBox("first_name", x => x.first_name)%>
<%= Html.TextBoxFor(model => model.first_name) %> 
AxelEckenberger
  • 16,628
  • 3
  • 48
  • 70
  • 1
    Thanks for taking a look. I fixed the case on (model => Model.first_name) to (model => model.first_name) but it hasn't made any difference. I've added more background about what I'm doing in case that helps. –  Feb 19 '10 at 16:18