8

This is just for curiosity

Why does this code work:

Html.TextBoxFor(x => x.Age, new { @Value = "0"})

and this doesn't:

Html.TextBoxFor(x => x.Age, new { @value = "0"})

Note the uppercase 'V' in @Value

I know value is a keyword, but so is readonly and it works. It's not necessary to use @Readonly (with uppercase 'R').

Does anybody have a clue?

Diego
  • 16,436
  • 26
  • 84
  • 136
  • Value is reserved, while value isnt. – Botonomous Jan 03 '13 at 16:04
  • What do you mean by "work"/"doesn't work"? – CodesInChaos Jan 03 '13 at 16:36
  • @CodesInChaos see the comments here: http://stackoverflow.com/a/3287411/310276 – Diego Jan 03 '13 at 16:45
  • 1) Yours uses `@value` not `value`, so `value` being a keyword shouldn't matter. 2) Even with `value` it should work, since `value` is no keyword in an initializer. | So this doesn't seem like a simple C# issue to me, but rather like a ASP.net MVC/`TextBoxFor` issue. I suspect a property called `value` has a special meaning for `TextBoxFor` and not for C#. – CodesInChaos Jan 03 '13 at 16:52

3 Answers3

6

InputExtensions.TextBoxFor special cases cases a few attribute names, among them value(case sensitive). This is unrelated to C# keywords.

In particular the value obtained from the expression parameter takes precedence of a property called value you pass into the htmlAttributes parameter.

Taking a look at your example:

  • If you use Html.TextBoxFor(x => x.Age, new { @value = "0"}) it will compile, but TextBoxFor will override the value attribute with the value x.Age evaluates to.

  • If you use Html.TextBoxFor(x => x.Age, new { @Value = "0"}) it will compile, and you will get two entries in the attribute dictionary, one Value that's "0", and one value, that's x.Age.

    I expect the output to be something nonsensical like <input Value="0" value="..." type="text"/>.

dlebech
  • 1,817
  • 14
  • 27
CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • 2
    It is not rendering both `Value` and `value`. It renders just `value`. (Mvc 4 and Razor 2) – Diego Jan 03 '13 at 18:59
  • 1
    I just checked and it is rendering both `Value` and `value` with ASP.NET MVC 3 and ASPX views – Jonas at Software Journey Feb 15 '13 at 11:57
  • 1
    Using both Firefox' and Chrome's "inspect element" will show only one `value` attribute. However, using "view source" or something similar will reveal that there is indeed both a `Value` and a `value` attribute. It seems the browser just shows the first occurrence of `value`, no matter the case. Indeed, it also works with `vAlue` (tested just now). MVC 4 and Razor 2. – dlebech Jul 29 '13 at 10:17
  • @dlebech thanks, I also saw Edge's inspector showing only one value attribute, but you're right, the source shows two attributes. For this reason I'm using the TextBox helper instead (because it has an explicit parameter for setting the value attribute) – DigitalDan Jan 20 '17 at 14:35
3

I'm not 100% sure but, that could be value is a keyword in properties, readonly isn't. Look at properties from MSDN.

enter image description here

enter image description here

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
  • 2
    Doesn't make sense to me. The `@` should escape the keyword, so `@value` results in a property called `value`. If this doesn't work, it must be some weirdness related to `TextBoxFor` or Razor and not simply due to being a C# keyword. – CodesInChaos Jan 03 '13 at 16:42
  • 1
    It makes sense because it's not just a reserved work. Inside a setter, it's a method parameter. – Rotem Jan 03 '13 at 17:07
  • 1
    Just try it with some other C# keyword that's not special cased by `TextBoxFor`. – CodesInChaos Jan 03 '13 at 17:23
  • I agree with @CodesInChaos. It does not make sense. It is actually a consequence of the MVC framework that always overwrites the `value` attribute as described in @CodesInChaos answer. – dlebech Jul 29 '13 at 10:21
0

My guess is that the MVC code is hard coded to look for Value because a MS engineer intended you to always use PascalCase property names, since that's their typical convention and PascalCase avoids conflicts with non-contextual keywords such as class. Notice how PascalCase properties get rendered in the HTML as lowercase.

The reason is not about value being a keyword, since it's a contextual keyword in C# and only has special meaning (and thus turns blue in the IDE) in property getters and setters. It has no special meaning in the anonymous type passed to TextBoxFor.

Edward Brey
  • 40,302
  • 20
  • 199
  • 253
  • It also works with `vAlue`. It depends on the browser rendering. See my comment for the answer by CodesInChaos. – dlebech Jul 29 '13 at 10:18