Search code examples
jqueryasp.net-core-2.1razor-pages

Datepicker in razor pages always appears blank


This is a seemingly simple thing, but I have not gotten it to work. I am building a simple file upload form and I want to have a date uploaded field. I've made the model, I want to save both the date and time:

[DataType(DataType.DateTime)]
public DateTime DateUploaded { get; set; }

Then in the view:

<input asp-for="DateUploaded" class="form-control" value="@DateTime.Now.ToString("yyyy-MM-dd HH:mm")" />

But the datepicker always appears blank, like this, I want it to automatically load the current date and time down to the minute:

enter image description here Though the source shows there is a value. which leads me to believe it might be related to jquery, but I have no idea what that might be and I am not even sure what to look for. Attempts so far have not yielded a solution.

<input class="form-control" value="2018-09-13 13:36" type="datetime-local" data-val="true" data-val-required="The DateUploaded field is required." id=" name="DateUploaded" />

To the model I have also attempted to add the following without result:

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm}", ApplyFormatInEditMode = true)]

Solution

  • First, when you are binding to a property of type DateTime (and a DataType of DateTime), the InputTagHelper is going to render an input with a type of datetime-local. This will trigger supporting browsers to show a datepicker control, which is what you're seeing here. However, this built-in control only works with date/time values in ISO format, which your date time string is not. If the string cannot be parsed as an ISO datetime, it's treated as null, and therefore no value is being shown.

    Long and short, you need to feed it a datetime string like: yyyy-MM-dd\Thh:mm:ss, or simply o.

    @DateTime.Now.ToString("o")
    

    Second, when binding to a particular property (using asp-for), you should not supply a value manually. Instead, if you want the property to default to DateTime.Now, set that as the default for the property:

    [DataType(DataType.DateTime)]
    public DateTime DateUploaded { get; set; } = DateTime.Now;
    

    In which case, you won't actually need to format it at all, as Razor will take care of that for you.

    Finally, using DateTime.Now is a really bad idea for a web application. The value will be the current time on the server, and almost assuredly won't the "now" for the user, unless they just happen to be in the same timezone as your server resides. Instead, use DateTime.UtcNow or even better DateTimeOffset.UtcNow.