A Closer Look at the HiddenInput Attribute in MVC 2
- by Steve Michelotti
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.