Reputation: 2208
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
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