Steve Michelotti

A .NET Developer's Toolbox

  Home  |   Contact  |   Syndication    |   Login
  201 Posts | 0 Stories | 1110 Comments | 51 Trackbacks

News

View Steve Michelotti's profile on LinkedIn

profile for Steve Michelotti at Stack Overflow, Q&A for professional and enthusiast programmers




Google My Blog

What I'm Reading:

Shelfari: Book reviews on your book blog

Tag Cloud


Archives

Post Categories

Code

Publications

MVC 2 includes an attribute for model metadata called the HiddenInput attribute. The typical usage of the attribute looks like this (line #3 below):

   1:  public class PersonViewModel
   2:  {
   3:      [HiddenInput(DisplayValue = false)]
   4:      public int? Id { get; set; }
   5:      public string FirstName { get; set; }
   6:      public string LastName { get; set; }
   7:  }

So if you displayed your PersonViewModel with Html.EditorForModel() or Html.EditorFor(m => m.Id), the framework would detect the [HiddenInput] attribute metadata and produce HTML like this:

   1:  <input id="Id" name="Id" type="hidden" value="21" />

This is pretty straight forward and allows an elegant way to keep the technical key for your model (e.g., a Primary Key from the database) in the HTML so that everything will be wired up correctly when the form is posted to the server and of course not displaying this value visually to the end user. However, when I was giving a recent presentation, a member of the audience asked me (quite reasonably), “When would you ever set DisplayValue equal to true when using a HiddenInput?” To which I responded, “Well, it’s an edge case. There are sometimes when…er…um…people might want to…um…display this value to the user.” It was quickly apparent to me (and I’m sure everyone else in the room) what a terrible answer this was. I realized I needed to have a much better answer here.

First off, let’s look at what is produced if we change our view model to use “true” (which is equivalent to use specifying [HiddenInput] since “true” is the default) on line #3:

   1:  public class PersonViewModel
   2:  {
   3:      [HiddenInput(DisplayValue = true)]
   4:      public int? Id { get; set; }
   5:      public string FirstName { get; set; }
   6:      public string LastName { get; set; }
   7:  }

Will produce the following HTML if rendered from Htm.EditorForModel() in your view:

   1:  <div class="editor-label">
   2:      <label for="Id">Id</label>
   3:  </div>
   4:  <div class="editor-field">
   5:      21<input id="Id" name="Id" type="hidden" value="21" /> 
   6:      <span class="field-validation-valid" id="Id_validationMessage"></span>
   7:  </div>

The key is line #5. We get the text of “21” (which happened to be my DB Id in this instance) and also a hidden input element (again with “21”).

So the question is, why would one want to use this? The best answer I’ve found is contained in this MVC 2 whitepaper:

When a view lets users edit the ID of an object and it is necessary to display the value as well as to provide a hidden input element that contains the old ID so that it can be passed back to the controller.

Well, that actually makes sense. Yes, it seems like something that would happen *rarely* but, for those instances, it would enable them easily. It’s effectively equivalent to doing this in your view:

   1:  <%: Html.LabelFor(m => m.Id) %>
   2:  <%: Model.Id %>
   3:  <%: Html.HiddenFor(m => m.Id) %>

But it’s allowing you to specify it in metadata on your view model (and thereby take advantage of templated helpers like Html.EditorForModel() and Html.EditorFor()) rather than having to explicitly specifying everything in your view.

posted on Monday, June 14, 2010 2:09 PM

Feedback

# re: A Closer Look at the HiddenInput Attribute in MVC 2 6/14/2010 3:41 PM Adam Tolley
In the code the '21' does not appear to be in a form control, or have a name associated with it. So this data doesn't seem to have a path back to the application - and the whitepaper seems to contradict itself.

The paper also says this:

When the attribute is set to true (or no parameter is specified), the following occurs:

In display templates, a label is rendered and the value is displayed to the user.
In editor templates, a label is rendered and the value is rendered in a hidden input element.
When the attribute is set to false, the following occurs:

In display templates, nothing is rendered for that field.
In editor templates, no label is rendered and the value is rendered in a hidden input element.

which confirms the last few lines of this post.

If we were hand coding the views, this would likely be a senseless thing to do (or at least very unintuitive), but it serves as an avenue for the templated helpers to render the fields appropriately using only the metadata.

# re: A Closer Look at the HiddenInput Attribute in MVC 2 6/14/2010 4:30 PM Steve
@Adam - on line #5, "21" appears by itself (i.e,. not in a form control) *and* also inside a hidden input element. So the "old" value has a path back to the application. A "new" value would have a have a separate property in the view model and that would be the path back to the application. Again, this would be in the case would end user wanted to change the ID *and* the server side needed to see the old value as well (so it knew which row to modify). So the whitepaper does not actually contradict itself.

But yes, actually I totally agree with you that this is not a very intuitive thing to do for normal cases.

# re: A Closer Look at the HiddenInput Attribute in MVC 2 6/28/2010 12:11 PM matt
How is this not a violation of SOC ?
View specific information in the model?
Really?

# re: A Closer Look at the HiddenInput Attribute in MVC 2 1/25/2012 6:08 AM Sobari
I put the [HiddenInput(DisplayValue=false)]
to my primary key, but still that field is shown, any idea what shoud be inspected?

# re: A Closer Look at the HiddenInput Attribute in MVC 2 1/25/2012 9:09 AM Steve Michelotti
@Sobari - I'm not sure. What type of editor template are you using?

# re: A Closer Look at the HiddenInput Attribute in MVC 2 3/29/2012 9:29 PM Diego
Also, DisplayValue=true is necesasry if you have a viewmodel that derives from another where a property already has [HiddenInput] applied.. but u want it to be visible in the derived type..

Post A Comment
Title:
Name:
Email:
Comment:
Verification: