我试图显示一个表单,允许用户为一个人输入新的作业.我正在使用DateTime.cshtml EditorTemplate来处理赋值的DateTime值.不可为空的DateTime工作正常.可空的DateTime导致"InvalidOperationException:Nullable对象必须具有值".
我有一个看起来像这样的简单viewmodel:
AssignmentViewModel.cs:
public Person Person { get; set; }
public Assignment NewAssignment { get; set; }
Run Code Online (Sandbox Code Playgroud)
Assignment.cs包含:
public DateTime AssignmentStartDate { get; set; }
public DateTime? AssignmentEndDate { get; set; }
Run Code Online (Sandbox Code Playgroud)
我的AssignmentController Create()方法如下所示:
public ViewResult Create(int personId)
{
Person person = personRepository.GetPersonById(personId);
var newAssignment = new AssignmentViewModel { Person = person, NewAssignment = new Assignment() };
return View(newAssignment);
}
Run Code Online (Sandbox Code Playgroud)
我的Create.cshtml视图如下所示:
@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 />
}
Run Code Online (Sandbox Code Playgroud)
我的DateTime.cshtml EditorTemplate看起来像:
@model DateTime?
@{
String modelValue = "";
if (Model.HasValue)
{
if (Model.Value != DateTime.MinValue)
{
modelValue = Model.Value.ToShortDateString();
}
}
}
@Html.TextBox("", modelValue, new { @class = "datePicker" })
Run Code Online (Sandbox Code Playgroud)
当我尝试加载Create视图时,我在"@ Html.EditorFor(x => x.NewAssignment.AssignmentEndDate.Value)"行中得到了上面提到的异常.
您可能想知道我为什么要传递AssignmentEndDate.Value.Date而不是仅传递AssignmentEndDate; 原因是因为我试图达到将DateTime拆分为Date和TimeOfDay字段并将其与DateTimeModelBinder重新组合的程度.我使用的技术类似于此处和此处显示的技术.
我可以通过更改我的控制器Create()方法来实现将AssignmentEndDate设置为DateTime.MinValue的ViewModel来绕过错误,但对于可以为空的DateTime来说这似乎完全错误:
var newAssignment = new AssignmentViewModel
{
Person = person,
NewAssignment = new Assignment { AssignmentEndDate = DateTime.MinValue }
};
Run Code Online (Sandbox Code Playgroud)
在通过为可为空的DateTime提供值"绕过"错误之后发生了一些奇怪的事情; 不需要的可空DateTime属性(AssignmentEndDate.Date)无法通过客户端验证.尝试提交表单会以红色突出显示该字段.
我该如何正确处理?
问题是,你试图取回AssignmentEndDate.Value.Date
,但AssignmentEndDate
是null
,这会导致这个错误.
由于你的编辑器模板接受了一个DateTime?
,你应该传递AssignmentEndDate
.换句话说,.Value.Date
从视图中删除:
@Html.EditorFor(x => x.NewAssignment.AssignmentEndDate, new { cssClass = "datePicker" })
Run Code Online (Sandbox Code Playgroud)
由于您的编辑器模板正在使用ToShortDateString()
,因此无需从截断日期"截断"时间.
关于你想要单独的"日期"和"时间"编辑的愿望:
你可以这两种方式做到这一点.
1 - 您当前的DateTime?
编辑器为其渲染一个字段Model.Value.Date
,因此您可以简单地将其扩展为渲染字段Model.Value.TimeOfDay
.例:
@{
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"})
Run Code Online (Sandbox Code Playgroud)
2 - 您可以将上述功能拆分为2个独立的编辑器,"DateOnly"和"TimeOnly".然后,更新您的视图以调用两个编辑器:
@Html.EditorFor(x => x.NewAssignment.AssignmentEndDate, "DateOnly")
@Html.EditorFor(x => x.NewAssignment.AssignmentEndDate, "TimeOnly")
Run Code Online (Sandbox Code Playgroud)
选择取决于您,以及您是否要将日期和时间部分分开或一起保留,但这就是我要解决此问题的方法.
归档时间: |
|
查看次数: |
16803 次 |
最近记录: |