0

I'm new to ASP.NET MVC but I haven't been able to find an explanation for this.

My questions is regarding the difference in the value attribute in the generated HTML when I use @HtmlTextBox() vs. @HtmlTextBoxFor().

I can set the initial value for an <input> using @Html.TextBox() like this:

@Html.TextBox("Phone", "Initial Value", htmlAttributes: new { id = "txt_phone" })

The generated HTML is just what you'd expect:

<input id="txt_phone" name="Phone" type="text" value="Initial Value" />

Please notice the generated value attribute above.

Using @HtmlTextBoxFor() is a different. Please note that I have a very simple model in my view. It has a Phone property which is a String.

Here's an attempt at setting an initial value using @Html.TextBoxFor():

@Html.TextBoxFor(x => x.Phone, htmlAttributes: new { id = "txt_phone", value="Initial Value" })

The generated HTML, however, does not reflect the value attribute:

<input id="txt_phone" name="Phone" type="text" value="" />

My first question is, "why did the generated HTML not reflect the 'Initial Value' text in my value attribute?"

As many of you know, the "right way" to set the initial value with @HtmlTextBoxFor() is like this:

@Html.TextBoxFor(x => x.Phone, htmlAttributes: new { id = "txt_phone", Value = "Initial Value" })

But look at the generated HTML:

<input Value="Initial Value" id="txt_phone" name="Phone" type="text" value="" />

As you can see it generates a Value attribute (with a capital V) yet it still generates a value attribute with a lowercase v and an empty string!.

My second question then, is, why does @Html.TextBoxFor() require a captial V in Value yet still generate a lower-case v, value with an empty string?

Thanks

1 Answer 1

1

The answer to "why?" is because this is not the way you're supposed to pass a value. The HTML helpers use a bit of fairly complex logic to determine what the value of a field should be, and because it varies based on a number of different circumstances, your attempt at adding a manual value are largely ignored.

The first place Razor looks for a value is in ModelState, which is composed of the data from Request, ViewData and ViewBag. Then, it looks on the view's Model. Finally, it will fallback to the "default" value, which really only applies with the non-For helpers, where you can specify the value to default to. The reason you can't do the same with the For helpers is because they are bound to an actual property, and therefore, take that property's value, even if it's just the default of null or 0 or something.

Long and short, if you want to bind to a property and have it default to a specific value, then that value needs to be the default for the property. For example:

private string phone;
public string Phone
{
    get { return phone ?? "Initial Value"; }
    set { phone = value; }
}

Now, the property itself will always return "Initial Value" if it's previously unset, so your form field will as well.

Sign up to request clarification or add additional context in comments.

2 Comments

Chris, I've not doubt you're right but some empirical evidence is not consistent with what you mentioned, or, more likely, is a result of my misunderstanding. Let's say we have the same code you show above, along with this Razor bit: @Html.TextBox("Phone", null, htmlAttributes: new { id = "txt_phone" }) Even though I am not using the -For() form, I still get binding to the model. Now if I modify the Razor to this: @Html.TextBox("Phone", "Big Dog", htmlAttributes: new { id = "txt_phone" }) I override the model's default. It seems both forms of helpers participate in binding.
The main thing I was getting hung up on (and still am) is this weirdness where there is a capital V for value in the -For form of the helper. I'm not so concerned about the binding, What I was really wondering about is what appears to be the asymmetry in the use of the value attribute between the non-For form of the helper and the -For form.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.