MVC 默认绑定器未绑定嵌套 class
MVC Default binder not binding a nested class
我在获取 MVC 默认绑定器序列化嵌套对象时遇到问题。
我做了很多研究,试图找出我做错了什么,但我没有看到。
模型附带了所有创建的嵌套对象(由构造函数提供,没有它们什么也不会创建)但是没有数据被序列化。
我已经覆盖了 DefaultBinder 并添加了断点来找出失败的原因。它似乎将 Start 和 End 识别为 DateTimePart,但不对它们执行任何操作。
我花了很多时间试图阅读和理解 DefaultBinder 的逻辑,我读过的所有内容似乎都表明这应该有效,但事实并非如此。任何帮助或大胆的猜测都将不胜感激,因为这让我发疯。
此外,为了清楚起见,我意识到我可以使用自定义活页夹来克服这个问题,但在我这样做之前,我想了解为什么这不适用于默认活页夹。
这是控制器:
public class TestController : Controller
{
// GET: Test
public ActionResult Index()
{
StartEndTime se = new StartEndTime();
se.Start = new DateTimeParts();
se.End = new DateTimeParts();
se.Start.Date = new DateTime(2015, 2, 22, 13, 12, 0);
se.End.Date = new DateTime(2015, 3, 1, 10, 43, 0);
return View(se);
}
[HttpPost]
public ActionResult Index(StartEndTime se)
{
return RedirectToAction("Index");
}
}
这是视图(仅作为示例,复制了问题,但真实的视图对时间和日期的处理方式不同)
@model Models.StartEndTime
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.EditorFor(model => model.Start.DatePart)
@Html.EditorFor(model => model.Start.TimePart)
@Html.EditorFor(model => model.End.DatePart)
@Html.EditorFor(model => model.End.TimePart)
@Html.SButtonSave()
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
生成的相关部分HTML:
<input name="Start_DatePart" id="Start_DatePart" class="text-box single-line form-control datepicker" type="text" value="2015-02-22">
<input name="Start_TimePart" id="Start_TimePart" class="text-box single-line form-control datepicker" type="text" value="0001-01-01">
<input name="End_DatePart" id="End_DatePart" class="text-box single-line form-control datepicker" type="text" value="2015-03-01">
<input name="End_TimePart" id="End_TimePart" class="text-box single-line form-control datepicker" type="text" value="0001-01-01">
最后是模型。我已经包含了所有内容,因为我不确定是什么导致了这个问题:
public class DateTimeParts
{
public DateTime? Date { get; set; }
public DateTime? DatePart
{
get
{
if (Date.HasValue)
return Date.Value.Date;
else
return null;
}
set
{
if (value.HasValue)
{
if (Date.HasValue)
Date = value.Value.Date.Date + Date.Value.TimeOfDay;
else
Date = value.Value.Date.Date;
}
else
{
Date = null;
}
}
}
public DateTime? TimePart
{
get
{
if (Date.HasValue)
return new DateTime() + Date.Value.TimeOfDay;
else
return null;
}
set
{
if (value.HasValue)
{
if (Date.HasValue)
Date = Date.Value.Date + value.Value.TimeOfDay;
else
Date = new DateTime() + value.Value.TimeOfDay;
}
else
{
Date = new DateTime();
}
}
}
}
public class StartEndTime
{
public DateTimeParts Start { get; set; }
public DateTimeParts End { get; set; }
public int Minutes
{
get
{
if (!Start.Date.HasValue || !End.Date.HasValue)
return 0;
else
return (int)(End.Date.Value - Start.Date.Value).TotalMinutes;
}
set
{
if (!Start.Date.HasValue)
return;
End.Date = Start.Date.Value + new TimeSpan(0, value, 0);
}
}
}
我敢打赌这是 C# 处理 DateTime
的方式。例如,0001-01-01
看起来不是有效日期,并且缺少时间戳。
您应该将 value
设置为如下内容:
string dateString = "5/1/2008 8:30:52 AM";
我想默认的活页夹会把它捡起来。使用 @Html.HiddenFor
进行测试。
我在获取 MVC 默认绑定器序列化嵌套对象时遇到问题。 我做了很多研究,试图找出我做错了什么,但我没有看到。
模型附带了所有创建的嵌套对象(由构造函数提供,没有它们什么也不会创建)但是没有数据被序列化。
我已经覆盖了 DefaultBinder 并添加了断点来找出失败的原因。它似乎将 Start 和 End 识别为 DateTimePart,但不对它们执行任何操作。
我花了很多时间试图阅读和理解 DefaultBinder 的逻辑,我读过的所有内容似乎都表明这应该有效,但事实并非如此。任何帮助或大胆的猜测都将不胜感激,因为这让我发疯。
此外,为了清楚起见,我意识到我可以使用自定义活页夹来克服这个问题,但在我这样做之前,我想了解为什么这不适用于默认活页夹。
这是控制器:
public class TestController : Controller
{
// GET: Test
public ActionResult Index()
{
StartEndTime se = new StartEndTime();
se.Start = new DateTimeParts();
se.End = new DateTimeParts();
se.Start.Date = new DateTime(2015, 2, 22, 13, 12, 0);
se.End.Date = new DateTime(2015, 3, 1, 10, 43, 0);
return View(se);
}
[HttpPost]
public ActionResult Index(StartEndTime se)
{
return RedirectToAction("Index");
}
}
这是视图(仅作为示例,复制了问题,但真实的视图对时间和日期的处理方式不同)
@model Models.StartEndTime
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.EditorFor(model => model.Start.DatePart)
@Html.EditorFor(model => model.Start.TimePart)
@Html.EditorFor(model => model.End.DatePart)
@Html.EditorFor(model => model.End.TimePart)
@Html.SButtonSave()
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
生成的相关部分HTML:
<input name="Start_DatePart" id="Start_DatePart" class="text-box single-line form-control datepicker" type="text" value="2015-02-22">
<input name="Start_TimePart" id="Start_TimePart" class="text-box single-line form-control datepicker" type="text" value="0001-01-01">
<input name="End_DatePart" id="End_DatePart" class="text-box single-line form-control datepicker" type="text" value="2015-03-01">
<input name="End_TimePart" id="End_TimePart" class="text-box single-line form-control datepicker" type="text" value="0001-01-01">
最后是模型。我已经包含了所有内容,因为我不确定是什么导致了这个问题:
public class DateTimeParts
{
public DateTime? Date { get; set; }
public DateTime? DatePart
{
get
{
if (Date.HasValue)
return Date.Value.Date;
else
return null;
}
set
{
if (value.HasValue)
{
if (Date.HasValue)
Date = value.Value.Date.Date + Date.Value.TimeOfDay;
else
Date = value.Value.Date.Date;
}
else
{
Date = null;
}
}
}
public DateTime? TimePart
{
get
{
if (Date.HasValue)
return new DateTime() + Date.Value.TimeOfDay;
else
return null;
}
set
{
if (value.HasValue)
{
if (Date.HasValue)
Date = Date.Value.Date + value.Value.TimeOfDay;
else
Date = new DateTime() + value.Value.TimeOfDay;
}
else
{
Date = new DateTime();
}
}
}
}
public class StartEndTime
{
public DateTimeParts Start { get; set; }
public DateTimeParts End { get; set; }
public int Minutes
{
get
{
if (!Start.Date.HasValue || !End.Date.HasValue)
return 0;
else
return (int)(End.Date.Value - Start.Date.Value).TotalMinutes;
}
set
{
if (!Start.Date.HasValue)
return;
End.Date = Start.Date.Value + new TimeSpan(0, value, 0);
}
}
}
我敢打赌这是 C# 处理 DateTime
的方式。例如,0001-01-01
看起来不是有效日期,并且缺少时间戳。
您应该将 value
设置为如下内容:
string dateString = "5/1/2008 8:30:52 AM";
我想默认的活页夹会把它捡起来。使用 @Html.HiddenFor
进行测试。