I'm writing an ASP.NET MVC3 application in C# and have found that calling Html.HiddenFor
in my view will render a DateTime
differently (and incorrectly) to if i was to call Html.DisplayFor
.
The model its taking the value from does have a DisplayFormat decorator and this seems to work for Html.DisplayFor
. The property in question is written as:
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime MeetingStartDate { get; set; }
And the view displays this using:
@Html.DisplayFor(model => model.MeetingStartDate)
@Html.HiddenFor(model => model.MeetingStartDate)
The DisplayFor call will render the date as 16/04/2012
however the HiddenFor will render it as value="04/16/2012 00:00:00"
.
I've tried changing the current culture to set a DateTimeFormat
but this had no effect.
The current culture is en-GB so it shouldn't be printing en-US dates anyway.
An in-view alternative using TextBoxFor will work if you specify the date format and the html hidden attribute.
@Html.TextBoxFor(model => model.CreatedDate, "{0:dd/MM/yyyy HH:mm:ss.fff}", htmlAttributes: new { @type = "hidden" })
If you want to generate a hidden field that respects the format you defined you could define a custom editor template to override the default one (~/Views/Shared/EditorTemplates/HiddenInput.cshtml
):
@if (!ViewData.ModelMetadata.HideSurroundingHtml)
{
@ViewData.TemplateInfo.FormattedModelValue
}
@Html.Hidden("", ViewData.TemplateInfo.FormattedModelValue)
and now you decorate your model property with the [HiddenInput]
attribute:
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
[HiddenInput(DisplayValue = false)]
public DateTime MeetingStartDate { get; set; }
and in your view:
@Html.DisplayFor(model => model.MeetingStartDate)
@Html.EditorFor(model => model.MeetingStartDate)
which will use the correct format for the hidden value:
<input data-val="true" data-val-required="The MeetingStartDate field is required." id="MeetingStartDate" name="MeetingStartDate" type="hidden" value="15/03/2012" />
Or you can outsmart the HiddenFor implementation and reuse the TextBoxFor instead and manually set type="hidden".
Something like this:
public static MvcHtmlString HiddenInputFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes = null)
{
IDictionary<string, object> htmlAttributesTmp = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
if (htmlAttributesTmp.ContainsKey("type"))
{
htmlAttributesTmp["type"] = "hidden";
}
else
{
htmlAttributesTmp.Add("type", "hidden");
}
return html.TextBoxFor(expression, htmlAttributesTmp);
}
In your model, for the Get function of the MeetingStartDate property can you return a formatted DateTime?
The DisplayFormat is not going to work for hidden values because MVC is creating a value in the hidden field that can be parsed correctly during the Form Submit action from the data that is currently set for the property.
What you have is expected actions by MVC.
if you give id like that the problem does not occur
<%= Html.TextBoxFor(model => Model.DiscountRate,new { @id = "DiscountRate", @Value=Model.DiscountRate})%>