The model's Hidden bool field remains False after it was set True in the controller [duplicate]
Asked Answered
B

1

5

I have this property in my ViewModel class:

public bool AreSimilarEntitiesChecked { get; set; }

In my controller I set its value 'true' and return the View with the model:

model.AreSimilarEntitiesChecked = true;

return View(model).WithWarning("Check the similar mentors before saving!");

On my View there is a form where I placed a hidden filed of this property:

@Html.HiddenFor(m => m.AreSimilarEntitiesChecked)

After the View returned with the model that contains the AreSimilarEntitiesChecked its value remains False desipte the fact I set the True valuse in the controller.

I don't know what could be wrong with it.

Generated HTML:

<input name="AreSimilarEntitiesChecked" id="AreSimilarEntitiesChecked"
 type="hidden" value="False" data-val-required="The AreSimilarEntitiesChecked
 field is required." data-val="true">
Buckshot answered 24/2, 2015 at 11:3 Comment(2)
The generated html shows value="False" so it's not being set to true. There is something else in your code preventing it being set, or is re-setting it.Toor
Are you doing model.AreSimilarEntitiesChecked = true; in the GET or POST method?Toor
C
7

I can't be sure that this is the problem from your question, but I would bet a lot of money that it is...

MVC's ModelState, which keeps a representation of the view's model data, preferentially pulls values from the POST data rather than getting them from a bound model. That is, if the HTTP POST contained a field called (case-insensitively) AreSimilarEntitiesChecked with the value False, then it does not matter what you set that property to in the viewmodel when rendering a view. ModelState will prefer the POSTed value to the viewmodel value.

The reason for this odd behaviour is, let's say you have a field where a user is supposed to enter an integer and they write "banana" instead. This is sent to the server for validation, which it fails. We want to render the view again, with "banana" still in the field and a message that that isn't an integer. But if the view preferentially rendered the viewmodel's data, that wouldn't be possible, as "banana" isn't an integer and can't be put in that viewmodel field. Hence the POST values are retained.

There are two options for fixing this. Either you can fix it for this field specifically:

ModelState.Remove("AreSimilarEntitiesChecked");

Or the nuclear option:

ModelState.Clear();

More information on this behaviour here: http://weblog.west-wind.com/posts/2012/Apr/20/ASPNET-MVC-Postbacks-and-HtmlHelper-Controls-ignoring-Model-Changes

Cirilla answered 24/2, 2015 at 11:31 Comment(2)
Thanks for the response, that was the problem.Buckshot
No worries. Took me about 5 hours to figure out the first time I hit it. I was posting one model to a method and returning a different one in the view, but it still behaves like this even if you switch model type. That'll teach me not to use Post-Redirect-Get, I guess.Cirilla

© 2022 - 2024 — McMap. All rights reserved.