Html.HiddenFor formats DateTime incorrectly in ASP

2019-04-06 22:41发布

问题:

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.

回答1:

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" })


回答2:

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" />


回答3:

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);
}


回答4:

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.



回答5:

if you give id like that the problem does not occur

<%= Html.TextBoxFor(model => Model.DiscountRate,new {  @id = "DiscountRate", @Value=Model.DiscountRate})%>