ASP.NET MVC中的DropDownListFor和TryUpdateModel

时间:2012-03-19 18:01:52

标签: c# asp.net-mvc razor

我有两个相关的POCO

public class Parent
{
   public Guid Id {get; set;}
   public IList<Child> ChildProperty {get; set;}
}

public class Child
{
   public Guid Id {get; set;}
   public String Name {get; set;}
}

我有一个带

的.cshtml Razor视图
<div>
    @{
        var children =
            new SelectList(Child.FindAll(), "Id", "Name").ToList();
    }
    @Html.LabelFor(m => m.Child)
    @Html.DropDownListFor(m => m.Child.Id, , children, "None/Unknown")
</div>

我想在我的控制器类中执行以下操作:

[HttpPost]
public ActionResult Create(Parent parent)
{
    if (TryUpdateModel(parent))
    {
        asset.Save();
        return RedirectToAction("Index", "Parent");
    }

    return View(parent);
}

这样,如果用户选择“None / Unknown”,则控制器中父对象的子值为null,但如果用户选择任何其他值(即从数据库中检索的子对象的ID),则父对象的子值被实例化并用该ID填充。

基本上我正在努力解决如何在HTTP无状态边界上保留可能的实体列表,以便其中一个实体被正确地重新水化并通过默认模型绑定器进行分配。我只是要求太多了吗?

1 个答案:

答案 0 :(得分:1)

  

我只是要求太多?

是的,你要求的太多了。

POST请求发送的所有内容都是所选实体的ID。不要指望得到更多。如果你想补充水分或任何你应该查询你的数据库。与您在GET操作中填充子集合的方式相同。

哦,你的POST动作有问题=&gt;您正在调用两次默认模型绑定器。

以下是两种可能的模式(我个人更喜欢第一种模式,但在某些情况下,当您想要手动调用默认模型活页夹时,第二种模式可能很有用):

[HttpPost]
public ActionResult Create(Parent parent)
{
    if (ModelState.IsValid)
    {
        // The model is valid
        asset.Save();
        return RedirectToAction("Index", "Parent");
    }

    // the model is invalid => we must redisplay the same view.
    // but for this we obviously must fill the child collection
    // which is used in the dropdown list
    parent.ChildProperty = RehydrateTheSameWayYouDidInYourGetAction();
    return View(parent);
}

或:

[HttpPost]
public ActionResult Create()
{
    var parent = new Parent();
    if (TryUpdateModel(parent))
    {
        // The model is valid
        asset.Save();
        return RedirectToAction("Index", "Parent");
    }

    // the model is invalid => we must redisplay the same view.
    // but for this we obviously must fill the child collection
    // which is used in the dropdown list
    parent.ChildProperty = RehydrateTheSameWayYouDidInYourGetAction();
    return View(parent);
}

在你的代码中,你把两者混合在一起是错误的。您基本上是两次调用默认模型绑定器。