Reputation: 483
The problem is Razor (MVC 5) renders out HiddenFor and Hidden helper incorrectly.
I have a view model like this:
public class MyViewModel
{
public bool BoolValueInsideViewModel { get; set; }
public MyViewModel()
{
BoolValueInsideViewModel = false;
}
}
and controller is simple as:
model = new MyViewModel();
model.BoolValueInsideViewModel = false;
return PartialView("_MyView", model);
Second line is just to be sure value is set to false. View looks like this:
@model MyViewModel
@Html.Hidden("BoolValueInsideViewModel", false)
@Html.Hidden("BoolValueNotInViewModel", false)
But on browser I get this:
<input data-val="true" data-val-required="The BoolValueInsideViewModel field is required." id="BoolValueInsideViewModel" name="BoolValueInsideViewModel" type="hidden" value="true">
<input id="BoolValueNotInViewModel" name="BoolValueNotInViewModel" type="hidden" value="False">
Note that I have like 15 other view models and controller methods in same controller works fine with same code (I use HiddenFor with strongly typed values normaly, here I changed to Hidden to show that it does not work even with hard coded value in view).
Putting a break point on view, shows model is actually has BoolValueInsideViewModel equal to false, but result on browser is different. Also I get the result via JQuery post callback, so I checked raw string returning from AJAX function and the value there is also "True" instead of false.
What I tried:
I know! It looks stupid and the most simplest thing on ASP.NET MVC, but I spent half a day on it. Other view models and partial views render correctly.
The weird thing is I don't have any data annotation on view model, but why it includes data validation attributes on the HTML element?
Upvotes: 2
Views: 1795
Reputation: 4572
For me, it was because my url had a query parameter with the same name as the viewmodel property. It seems the model binder is overriding the model value with that in the query string.
I've confirmed this by changing and removing the query string parameter and values, and get consistent results.
For example,
showMore=False
True
.Model.showMore
will be True
@HiddenFor(m => m.showMore)
, it will be False
showMore=True
, check the value of @HiddenFor(m => m.showMore)
, it will be True
showMore
, check the value of @HiddenFor(m => m.showMore)
, it will be True
Conclusion: the query string parameter value overrides the model value. Not sure if that is by design or a bug.
Upvotes: 1