21

I have a DateTime field in my Model. If I try to use this field in a strong typed partial view this way

<%= Html.TextBoxFor(model => model.DataUdienza.ToString("dd/MM/yyyy"), new { style = "width: 120px" })  %>

I will get the following compilation error at runtime

System.InvalidOperationException : Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.

Anyway if I use it removing the formatting, ToString("dd/MM/yyyy"), everything works but the field is formatted using the time part which I dont need at all.

Where I am doing wrong? Which is the correct way to handle this?

thanks for helping!

EDIT

This is the property declaration in the model class

[Required]
[DisplayName("Data Udienza")]
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime DataUdienza { get; set; }
Lorenzo
  • 29,081
  • 49
  • 125
  • 222

6 Answers6

24

i use this in mvc 4. it also works~

@Html.TextBoxFor(x => x.DatePurchase, "{0:yyyy-MM-dd}", new { @class = "dateInput", @placeholder = "plz input date" })
DarkMFJ
  • 443
  • 5
  • 12
  • 1
    Thanks very nice solution. but i really need to see why it has not used the culture info of the settings specified in the web config. – Desmond Dec 19 '12 at 10:11
19
<%= Html.EditorFor(model => model.DataUdienza) %>

And in your model:

[DisplayFormat(ApplyFormatInEditMode = true, 
               DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime DataUdienza { get; set; }

The drawback with EditorFor is that you cannot apply custom html attributes to the generated field. As an alternative you could use the TextBox helper:

<%= Html.TextBox("DataUdienza", Model.Date.ToString("dd/MM/yyyy"), new { style = "width: 120px" })%>
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Wow! Superfast. Thank you :) I'm gonna try it. But, in the meanwhile, how does this work if the field is a Nullable type? – Lorenzo Sep 17 '10 at 11:24
  • Works the same for nullable types. – Darin Dimitrov Sep 17 '10 at 11:27
  • I have tried to apply your solution but unfortunately does'nt work. I am gonna edit the post to add the model property declaration for your information. – Lorenzo Sep 17 '10 at 11:30
  • @Lorenzo, did you notice that `Html.EditorFor` should be used instead of `Html.TextBoxFor`? – Darin Dimitrov Sep 17 '10 at 11:32
  • @Darin: I have never used the EditorFor before. Anyway please consider that the two attributes (DataType and DisplayFormat) have been added now for trying your suggestion. – Lorenzo Sep 17 '10 at 11:36
  • Thanks for this, I'm using the textbox helper because I needed the field to be readonly so I must pass in new {@readonly="readonly"} Thanks – soniiic Jun 30 '11 at 14:27
12

Create an editor template called DateTime.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.DateTime?>" %>
<%=Html.TextBox("", (Model.HasValue ? Model.Value.ToString("MM/dd/yyyy") : string.Empty), ViewData) %>

Put it in your Views/Shared/EditorTemplates folder. Now when you call:

<%= Html.EditorFor(model => model.DataUdienza) %>

Your DateTime will be formatted without the time.

This will happen with all DateTimes called this way, though...

Custom html attributes can be used in this way:

<%= Html.EditorFor(model => model.DataUdienza, new {customAttr = "custom", @class = "class"}) %>

It passes through to the EditorTemplate as ViewData.

Marcel
  • 15,039
  • 20
  • 92
  • 150
Rohrbs
  • 1,855
  • 13
  • 11
2

At least if using razor, you can name the template, so you don't need to use the same template for all DateTimes:

@Html.EditorFor(m => m.StartDate, "Date")

where Date.cshtml contains a TextBoxFor or some other editor, like @JungleFreak had explained:

@model DateTime?

@Html.TextBox("", Model.HasValue ? Model.Value.ToShortDateString() : string.Empty, 
    new { data_datepicker = true })
Bondolin
  • 2,793
  • 7
  • 34
  • 62
1

Perhaps an extension method could be created:

    public static MvcHtmlString DateTimeFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
    {
        var compilationResult = expression.Compile();
        TValue dateValue = compilationResult((TModel)html.ViewDataContainer.ViewData.Model);
        var body = (MemberExpression)expression.Body;
        return html.TextBox(body.Member.Name, (Convert.ToDateTime(dateValue)).ToCustomDateFormat(), new { id = body.Member.Name, datepicker = true });
    }

the method ToCustomDateFormat could be an extension method for dateTime types which returns string value in desired format.

Usage:

@Html.DateTimeFor(x=>x.AnyDateTimeProperty)

Worked fine for me (for DateTime and DateTime? properties), although I am not sure if compiling the expression on run-time is a good idea.

bussa
  • 195
  • 2
  • 8
0

just add

@type = 'datetime-local'

For Example

@Html.TextBoxFor(x => x.DatePurchase, new { @class = "dateInput", @placeholder = "plz input date", @type = "datetime-local" })