17

What's up with this? The viewmodel variable is a bool with value true.

<%= Html.HiddenFor(m => m.TheBool) %>
<%= Html.Hidden("IsTimeExpanded",Model.TheBool) %>
<input type="hidden" value="<%=Model.TheBool%>" name="TheBool" id="TheBool">

Results in:

<input id="TheBool" name="TheBool" value="False" type="hidden">
<input id="TheBool" name="TheBool" value="False" type="hidden">
<input value="True" name="TheBool" id="TheBool" type="hidden">

What am I doing wrong? Why don't the helpers work as intended?

2
  • 4
    The answer is in stackoverflow.com/questions/4710447/… Commented Jul 8, 2013 at 12:03
  • This comment should be the correct answer - Helpers use POST values first. So if you're updating TheBool on postback and then displaying your model without doing a redirect/get, you may be displaying the wrong value. Commented Oct 11, 2016 at 20:23

4 Answers 4

15

1) use different (unique) ids

2) don't use this helper, use

<input type="hidden" name="the-name" 
  value="<%= Html.AttributeEncode(Model.TheBool) %>" id="TheBool_1216786" />
Sign up to request clarification or add additional context in comments.

6 Comments

The id is for example only, auto set by the helper and have nothing to do with the result. The question was: why don't the helpers work as intended?
It is question that should be addressed to MS, many people got so strange behaviour (I found at less one the same problem requests from other person). I tried to help how to resolve or avoid it. I don't work in MS. :) I have not got any thanks from you, so I don't understand why you so critical to my help.
I appreciate you trying to help me. It's just that you didn't help me. In fact you provided no relevant information that was not already in the question. Please direct me to the question you mentioned.
You can still use the helper and pass the ID using the htmlAttributes parameter - Html.Hidden("IsTimeExpanded", Model.TheBool, new { id="TheBool_1216786" })
|
3

As answered here the problem is that HTML helpers by default use the posted values (if available) then refer to the model. Personally I don't think this makes a whole bunch of sense and now wonder how many other bugs lie in wait throughout our platform.

Anyway, the solution posted in the aforementioned answer will solve the problem, just add this line before you return from the controller:

ModelState.Remove("TheBool")

And yes, it's a bit rubbish because you can only use a string reference... but it does work.

2 Comments

Yes - this works but I knwo that in years to come when I look at the code - i'll be thinking "why have a I done that."
I can't agree more and would wholeheartedly recommend liberal comments around the so called "fix". It is however a shortfall of the framework and one that cannot be avoided without such a cludge; that is to say that overriding OnActionExecute (or some such device) in an attempt to automate this would only lead to further unexpected behaviours and issues
0

I had similar and ended up getting round it like this. The situation is the user wants a Save and then confirm save scenario....

I chose to use the solution below rather than

ModelSate.Remove("OperationConfirmed");

(which does work) as I feel it is more intuative....

@{
  string btnSaveCaption = "Save Changes";
  if (Model.OperationConfirmed)
  {
    btnSaveCaption = "Confirm Save Changes";
    @Html.Hidden("OperationConfirmed", true)
  }          
} 

Comments

0

Here's an example in razor:

html:
@Html.HiddenFor(Model => Model.TheBool, new { @id = "hdnBool" })

javascript:
alert($('#hdnBool').val());

model:
public class MyModel()
{
  public bool TheBool{ get; set; }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.