Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Html.HiddenFor formats DateTime incorrectly in ASP.NET

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.

like image 350
Joey Ciechanowicz Avatar asked Mar 15 '12 17:03

Joey Ciechanowicz


3 Answers

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" })
like image 198
Fordy Avatar answered Sep 17 '22 20:09

Fordy


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" />
like image 44
Darin Dimitrov Avatar answered Sep 21 '22 20:09

Darin Dimitrov


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);
}
like image 33
Drejc Avatar answered Sep 18 '22 20:09

Drejc