EditorFor on nullable DateTime - “Nullable object must have a value.”

前端 未结 3 1043
醉梦人生
醉梦人生 2021-01-03 09:43

I am attempting to display a form that allows a user to input a new assignment for a person. I\'m using a DateTime.cshtml EditorTemplate to handle DateTime values for the a

相关标签:
3条回答
  • 2021-01-03 09:58

    create a DateTime.cshtml in your Shared/DisplayTemplate folder

    @model Nullable<DateTime>
    @(Model != null ? string.Format(ViewData.ModelMetadata.DisplayFormatString ?? "{0:d}", Model) : string.Empty)
    

    this supports metadata from datannotations to be used if found.

    0 讨论(0)
  • 2021-01-03 10:03

    UPDATE: GetValueOrDefault treats it as a DateTime and therefore the required Field validators are getting attached, because the original expression is for a datetime not a nullable datetime.

    Therefore the solution below doesn't work.

    Like the asker, I also used the DateTimeModelBinder from here: Here's the Link

    This is how I solved a similar situation:

    @Html.EditorFor(x => x.NewAssignment.AssignmentEndDate.GetValueOrDefault().Date)
    

    And this is what my DateTime EditorTemplate looks like:

    @model DateTime
    
    @Html.TextBox("", Model != default(DateTime) ? Model.ToShortDateString() : String.Empty, new { @class = "datepicker", @maxlength = "10" })
    
    0 讨论(0)
  • 2021-01-03 10:13

    The problem is that you're trying to retrieve the AssignmentEndDate.Value.Date, but AssignmentEndDate is null, which results in this error.

    Since your editor template accepts a DateTime?, you should just pass along the AssignmentEndDate. In other words, remove the .Value.Date from the view:

    @Html.EditorFor(x => x.NewAssignment.AssignmentEndDate, new { cssClass = "datePicker" })
    

    Since your editor template is using ToShortDateString(), there's no need to "truncate" the time from the date at all.

    Update

    Regarding your desire to have separate "Date" and "Time" editors:

    You can do this 2 ways.

    1 - Your current DateTime? editor renders a field for the Model.Value.Date, so you could simply extend this to also render a field for the Model.Value.TimeOfDay. Example:

    @{
      DateTime? modelDate = (Model == null) ? (DateTime?)null : Model.Value.Date;
      TimeSpan? modelTime = (Model == null) ? (TimeSpan?)null : Model.Value.TimeOfDay;
    }
    @Html.TextBox(..., modelDate, new{@class="datePicker"})
    @Html.TextBox(..., modelTime, new{@class="timePicker"})
    

    2 - You could split the above functionality into 2 separate editors, "DateOnly" and "TimeOnly". Then, update your view to call both editors:

    @Html.EditorFor(x => x.NewAssignment.AssignmentEndDate, "DateOnly")
    @Html.EditorFor(x => x.NewAssignment.AssignmentEndDate, "TimeOnly")
    

    The choice is up to you, and whether you want to keep the Date and Time parts separate or together, but this is how I'd go about solving this problem.

    0 讨论(0)
提交回复
热议问题