Tom Baxter
Tom Baxter

Reputation: 2208

Setting an MVC TextBox to Initial Value in Razor

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

Upvotes: 0

Views: 7481

Answers (1)

Chris Pratt
Chris Pratt

Reputation: 239440

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.

Upvotes: 1

Related Questions