DropDownListFor and TryUpdateModel in ASP.NET MVC

本文关键字:NET MVC ASP in and TryUpdateModel DropDownListFor | 更新日期: 2023-09-27 18:28:13

我有两个相关的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);
}

这样,如果用户选择"无/未知",则控制器中父对象的子值为空,但如果用户选择任何其他值(即从数据库检索的子对象的ID),则父对象的个子值将被实例化并填充该ID。

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

DropDownListFor and TryUpdateModel in ASP.NET MVC

我是不是要求太多了?

是的,你要求太高了。

与POST请求一起发送的只是所选实体的ID。不要期望得到更多。如果你想补充水分或其他什么,你应该查询你的数据库。与您在GET操作中填充子集合的方式相同。

哦,你的POST操作有问题=>你调用了两次默认的模型绑定器。

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

[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);
}

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