60

I have an MVC4 site, with (as part of a hidden form):

<input name="somefield" type="hidden" value="@ViewBag.Test"/>

The value of ViewBag.Test is true. The form field is posting to an input parameter of the form:

public ActionResult SomeAction(bool somefield = false, ...)

but somefield is always false. Upon investigating, I see that the source code has:

<input name="somefield" type="hidden" value="value"/>

However, I know this used to work. What has happened, and what can I do?

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Similar question: http://stackoverflow.com/questions/13451051/boolean-string-comparison-in-conditional-attribute-with-mvc4-razor-2-returns-u – webdeveloper Nov 19 '12 at 14:30
  • And another related-but-different (nulls this time): http://stackoverflow.com/questions/8061647/conditional-html-attributes-using-razor-mvc3 – Marc Gravell Nov 19 '12 at 14:35
  • 1
    I hope you've reported it as a bug. That seems reasonable for things like `disabled` or `checked` but definitely wrong for `value`. – tvanfosson Nov 19 '12 at 15:00
  • @tvanfosson I can see the logic of it - but it is a change. Not sure I'd call it a bug though. Breaking change, maybe – Marc Gravell Nov 19 '12 at 16:48
  • @MarcGravell I'd rather see less of a blanket solution and more of a targeted solution. Having said that, I haven't actually looked at the (new) code. Setting `value` to `"value"` seems definitely wrong. That, I think, is the bug. – tvanfosson Nov 19 '12 at 16:54

2 Answers2

80

This behaviour changed between MVC3 and MVC4. In MVC3, if you have:

<input name="somefield" type="hidden" someprop="@(SomeBooleanExpression)"/>

it would write very literally:

<input name="somefield" type="hidden" someprop="True"/>

However, in MVC4, it follows the "checkbox" etc rules, so if the value is true you get:

<input name="somefield" type="hidden" someprop="someprop"/>

and if it is false it is omitted completely:

<input name="somefield" type="hidden"/>

To get around this, consider .ToString():

<input name="somefield" type="hidden"
   someprop="@(SomeBooleanExpression.ToString())"/>

which then follows string rules rather than boolean rules.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 1
    Has anyone noticed the behavior where if there is a space between the value property and the equals sign, then the boolean is evaluated and assigned as expected. i.e. 'value =@(someBoolean)' will yield 'value="True"' whereas 'value=@(someBoolean) will yield 'value="value"' – mcolegro Sep 11 '14 at 15:37
  • @mcolegro heh, that's fun if true. Note there's Aldo a different behaviour for `@:` lines than for regular HTML blocks. – Marc Gravell Sep 11 '14 at 17:02
  • This worked, just when I think I understand areas like this in MVC4, I get hung up on things like this. Thanks for this answer, however, I don't get why it defaults to, "True", rather than "true" toLower() easily resolves this though. – eaglei22 Apr 04 '17 at 15:06
  • `.ToString()` was the solution for me. Thank you so much! I was already doubting my eyes! What a behavior! – nrod Nov 20 '18 at 08:44
-1

initialized Boolean values bool something =false;

then convert this value into string like,

<input name="somefield" type="hidden" value="@something.ToString()>

                   OR

initialized string something ="false"; < input name="somefield" type="hidden" value="@something" >

then we can read

    public ActionResult Somemethod(bool something) => you can get Boolean value here 
    {
    }