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 assignment. The non-nullable DateTime works fine. The nullable DateTime causes an "InvalidOperationException: Nullable object must have a value."
I have a simple viewmodel that looks like this:
AssignmentViewModel.cs:
public Person Person { get; set; }
public Assignment NewAssignment { get; set; }
Assignment.cs contains:
public DateTime AssignmentStartDate { get; set; }
public DateTime? AssignmentEndDate { get; set; }
My AssignmentController Create() method looks like:
public ViewResult Create(int personId)
{
Person person = personRepository.GetPersonById(personId);
var newAssignment = new AssignmentViewModel { Person = person, NewAssignment = new Assignment() };
return View(newAssignment);
}
My Create.cshtml view looks like this:
@model AssignmentViewModel
@using (Html.BeginForm("Create", "Assignment"))
{
@Html.Hidden("NewAssignment.PersonId", Model.Person.PersonId)
@Html.LabelFor(x => x.NewAssignment.AssignmentStartDate):
@Html.EditorFor(x => x.NewAssignment.AssignmentStartDate.Date, new { cssClass = "datePicker" })
<br />
@Html.LabelFor(x => x.NewAssignment.AssignmentEndDate):
@Html.EditorFor(x => x.NewAssignment.AssignmentEndDate.Value.Date, new { cssClass = "datePicker" })
<br />
<input type="submit" value="Send />
}
My DateTime.cshtml EditorTemplate looks like:
@model DateTime?
@{
String modelValue = "";
if (Model.HasValue)
{
if (Model.Value != DateTime.MinValue)
{
modelValue = Model.Value.ToShortDateString();
}
}
}
@Html.TextBox("", modelValue, new { @class = "datePicker" })
When I attempt to load the Create view, I get the exception mentioned above on the line "@Html.EditorFor(x => x.NewAssignment.AssignmentEndDate.Value)".
You may be wondering why I'm passing in AssignmentEndDate.Value.Date instead of just passing in AssignmentEndDate; the reason is because I'm trying to get to the point where I'm splitting DateTime into Date and a TimeOfDay field and recombine them with a DateTimeModelBinder. I am using a similar technique to the one shown here and here.
I -can- bypass the error, by changing my controller Create() method to instantiate the ViewModel with AssignmentEndDate set to DateTime.MinValue, but this seems completely wrong for a nullable DateTime:
var newAssignment = new AssignmentViewModel
{
Person = person,
NewAssignment = new Assignment { AssignmentEndDate = DateTime.MinValue }
};
Something strange happens after I "bypass" the error by supplying a value for the nullable DateTime; the un-required nullable DateTime property (AssignmentEndDate.Date) fails client side validation. Trying to submit the form highlights the field in red.
How can I handle this correctly?