36

I am trying to find me feet with MVC4 Razor and I'm stuck with this simple problem.

When I use @Html.DisplayFor the model is always sent back as NULL, but when I use @Html.TextBoxFor this model is fully populated, what am I missing?

Thanks in advance

Jacques
  • 747
  • 1
  • 8
  • 19
  • I need to display the fields as "labels". This is why; the purpose of this view is to enable the user to view the data before submitting it to the database. Any ideas how I can achieve this? – Jacques Jun 15 '12 at 19:38

6 Answers6

63

This is a common issue that many people miss in the asp.net mvc framework. Not just the difference in the helpers such as HiddenFor, DisplayFor, TextBoxFor - but how exactly the framework sets up automatically collecting and validating these inputs. The magic is all done with HTML5's data-* attributes. You will notice when looking at the input tag generated that there are going to be some extra properties in the form of data-val, data-val-required, and perhaps some additional data properties for types, for example numerics would be data-val-number.

These data attributes allow the jQuery extension jquery.validate.unobtrusive.js to parse the DOM and then decide which fields to validate or generate error messages.

The actual collection of posted data is reflected from the name property. This is what should map up to the model that is in the c# or vb [HttpPost] method.

Use HiddenFor when you want to provide posted data that the user does not need to be aware of.

Use DisplayFor when you want to show records but not allow them to be editted.

Use TextBoxFor when you want to allow user input or allow the user to edit a field.

EDIT

"the purpose of this view is to enable the user to view the data before submitting it to the database. Any ideas how I can achieve this?"

You could accomplish this with a duo of HiddenFor and DisplayFor. Use HiddenFor to have the values ready to be posted, and DisplayFor to show those values.

Travis J
  • 81,153
  • 41
  • 202
  • 273
16

DisplayFor will not do the Model binding. TextBoxFor will do because it creates a input element in the form and the form can handle it when it is being posted. If you want to get some data in the HttpPost action and you dont want to use the TextBoxFor, you can keep that pirticulare model proeprty in a hidden variable inside the form using the HiddenFor HTML helper method like this.

@using(Html.BeginForm())
{
  <p>The Type Name is</p> @Html.DisplayFor(x=>x.TypeName)
  @Html.HiddenFor(x=>x.TypeName)
  <input type="submit" value="Save" />
}
Shyju
  • 214,206
  • 104
  • 411
  • 497
  • Hi Shyju, I need to display the fields as "labels". This is why; the purpose of this view is to enable the user to view the data before submitting it to the database. Any ideas how I can achieve this? – Jacques Jun 15 '12 at 19:35
  • !@jacques: So use Displayfor for showing the data to the user and use HiddenFor to keep those in hidden variables and you are good to do a form post then. – Shyju Jun 15 '12 at 19:43
7

Use both DisplayFor and HiddenFor. DisplayFor simply displays the text and is not an input field, thus, it is not posted back. HiddenFor actually creates <input type="hidden" value="xxxx"/>

Mihai Iorga
  • 39,330
  • 16
  • 106
  • 107
2

DisplayFor builds out a HTML label, not an input. Labels are not POSTed to the server, but inputs are.

Justin Helgerson
  • 24,900
  • 17
  • 97
  • 124
  • This is not correct, for building labels there are "System.Web.Mvc.Html.LabelExtensions" methods like `Label` or `LabelFor` and `LabelForModel` – carloswm85 Aug 11 '22 at 15:19
1

I know this is a bit of an old question but you can roll your own, custom combined display control as shown below. This renders the model value followed by a hidden field for that value

@Html.DisplayExFor(model => Model.ItemCode)

Simply use what the framework already has in place

public static MvcHtmlString DisplayExFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> ex)
{
    var sb = new StringBuilder();
    sb.Append(htmlHelper.DisplayFor(ex));
    sb.Append(htmlHelper.HiddenFor(ex));

    return MvcHtmlString.Create(sb.ToString());
}
  • Nice one. I didn't use it (yet), but it is a good approach. I wonder if as far as 2022 is there some built-in solution like this one. This is called helper method, right? Where should I place it in the folder structure? – carloswm85 Aug 11 '22 at 15:25
0

Do you mean during a form post? If you use DisplayFor, this creates a element which does not contain any form values. Typically you use these in conjunction with each other to create a label for your textbox, then using the Html.TextBoxFor to allow users to modify the data element.

Example:

@Html.DisplayFor(x=>x.Item)
@Html.TextBoxFor(x=>x.Item)

Will Render

Item <a text input field following>

Or in HTML

<label for="Item">Item</label><input type="Text" id="Item" name="Item"/>
Tommy
  • 39,592
  • 10
  • 90
  • 121