I have several fields I display on most of my views in my MVC5 Code-First app: [created_date]
, [created_by]
, [modified_date]
, and [modified_by]
. For the user, I would like to include these also on my Edit()
view, but unlike my other fields I do not wish to have them editable (commonly created/by and modified/by data should NOT be editable).
This is how I have the fields declared on my Edit()
view currently:
<div class="form-group">
@*@Html.LabelFor(model => model.created_date, htmlAttributes: new { @class = "control-label col-md-2" })*@
<span class="control-label col-md-2">Created Date:</span>
<div class="col-md-10">
@Html.DisplayFor(model => model.created_date, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.created_date, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@*@Html.LabelFor(model => model.created_by, htmlAttributes: new { @class = "control-label col-md-2" })*@
<span class="control-label col-md-2">By:</span>
<div class="col-md-10">
@Html.DisplayFor(model => model.created_by, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.created_by, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@*@Html.LabelFor(model => model.modified_date, htmlAttributes: new { @class = "control-label col-md-2" })*@
<span class="control-label col-md-2">Modified Date:</span>
<div class="col-md-10">
@Html.DisplayFor(model => model.modified_date, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.modified_date, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@*@Html.LabelFor(model => model.modified_by, htmlAttributes: new { @class = "control-label col-md-2" })*@
<span class="control-label col-md-2">By:</span>
<div class="col-md-10">
@Html.DisplayFor(model => model.modified_by, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.modified_by, "", new { @class = "text-danger" })
</div>
</div>
Can anyone offer a way to make these fields read-only
?
I tried DisplayFor()
like on my Details
View, but when I go to save the record, the value in my EditorFor()
for [created_date]
changes from "2015-02-18" to "0001-01-01" and created_by
changes from my system username as previously set to null
with the validation message "The created_by field is required." I believe this has something to do with my model annotations for the fields, but I don't see why the DisplayFor()
is not passing the value through my controller like how the EditorFor()
does...?
Model Annotations:
[Required]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime created_date { get; set; }
[Required]
public string created_by { get; set; }
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
public DateTime? modified_date { get; set; }
public string modified_by { get; set; }
DisplayFor()
does not generate a control that posts back. You need to include a hidden input in addition to the display text, for example
<div class="form-group">
<span class="control-label col-md-2">@Html.DisplayNameFor(m => created_by)</span>
<div class="col-md-10">
@Html.DisplayFor(model => model.created_by
@Html.HiddenFor(m => created_by)
</div>
</div>
Another option is to make the textbox readonly
<div class="form-group">
@Html.LabelFor(model => model.created_by, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.TextBoxFor(model => model.created_by, new { @class = "form-control", @readonly = "readonly" })
</div>
</div>
Note also there is no point adding @Html.ValidationMessageFor()
Side note: There is nothing to stop a user changing the values of a hidden input (using FireBug for example), so as always, using a view model is the best approach (the view model would not include validation attributes on the 'readonly' properties) and then when posting, get the original data model and map the relevant view model properties to the data model before saving.