POST上的ViewModel对象child为null

时间:2014-11-16 16:41:15

标签: c# asp.net-mvc viewmodel

我有一个viewmodel,有两个属性,一个是POCO类,另一个是double,当控制器构建并发送viewmodel时,所有值都存在并在页面上工作。当我对viewmodel进行POST时,设置了double值,并且该对象存在,但内部的POCO类为null,而不是在发送对象时。

在下面的示例中,为什么在POSTed viewmodel对象上ticket.flight为空?

视图模型:

public class PayViewModel
{
    public virtual Ticket ticket { get; set; }
    public double amountToPay = 0.0;
    [Display(Name = "Amount To Pay")]
    [DataType(DataType.Currency)]
    [DisplayFormat(DataFormatString = "{0:N2}", ApplyFormatInEditMode = true)]
    public double AmountToPay
    {
        get
        {
            return amountToPay;
        }
        set
        {
            amountToPay = value;
        }
    }
}

控制器方法:

// GET: Tickets/Pay/5
public ActionResult Pay(int? id)
{
    if (id == null)
    {
        return RedirectToAction("Index");
    }
    Ticket ticket = db.tickets.Find(id);
    if (ticket == null)
    {
        return RedirectToAction("Index");
    }

    PayViewModel viewModel = new PayViewModel();
    viewModel.ticket = ticket;
    return View(viewModel);
}

// POST: Tickets/Pay/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Pay([Bind(Include = "AmountToPay,ticket,ticket.flight")]PayViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        viewModel.ticket.AmountPaid += viewModel.AmountToPay;
        if (viewModel.ticket.AmountPaid >= viewModel.ticket.flight.ticketPrice)
        {
            viewModel.ticket.status = TicketStatusType.CONFIRMED;
        }
        db.Entry(viewModel.ticket).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(viewModel.ticket);
}

查看代码 - https://gist.github.com/JonFriesen/f511a91b8e9a90c1b23c

1 个答案:

答案 0 :(得分:4)

在表单提交期间,浏览器仅提交input类型的字段。这意味着从您的视图中只有这些语句创建输入类型的字段:

@Html.HiddenFor(model => model.ticket.id)

@Html.EditorFor(model => model.AmountToPay, new { htmlAttributes = new { @class = "form-control" } })

当请求到达MVC应用程序时,绑定使用到达的值ticket.idAmountToPay来构造PayViewModel类型的对象。由于它在提交的值中找不到ticket.flight中的任何属性,因此它假定它不应存在,因此会为其分配默认值null。这是模型绑定器的预期行为。

如果您想要初始值,我建议使用以下方法之一:

  • POST上初始化数据库代码中的对象,并仅使用提交的AmountToPay值来执行处理。
  • 在视图中添加缺失字段的隐藏变量,例如@Html.HiddenFor(model => model.ticket.flight.source.airportCode)。在这种情况下,变量将被提交,因此对象将被完全填充。