绑定包含嵌套对象的ViewModel类

时间:2013-01-02 16:08:46

标签: c# asp.net-mvc selectlist selectlistitem

我创建了一个包含其他复杂类对象的类。

例如

class A {

    public int ID { set; get; }

    public string MyObjectName {set; get; }

    public B ObjectOfTypeB { set; get; }

}

class B {

    public int ID { set; get; }

    public int CategoryNumber { set; get; }

    public string CategoryDescription { set; get; }

}

现在我有一个控制器方法,它创建了A类型的对象。我为一个视图创建了我的模型(A类)。但由于A包含复杂类型,因此不知道如何为B类型创建输入字段。

在我的创建功能

// helper method to get a list of the possible B objects - 
// this method will eventually query a database. for now just static objects

private List<Category> getBobjects()
{
    List<B> bs = new List<B>();
    bs.Add(new B() { ID = 1, CategoryNumber = 2, CategoryDescription = "Config 1" });
    bs.Add(new B() { ID = 2, CategoryNumber = 3, CategoryDescription = "Config 2" });
    return bs;
}

[HttpGet]
public ActionResult Create()
{
    // Adding to the view bags the categories to display
    ViewBag.bs = getBobjects();
    return View();
}

在视图中

@Html.DropDownListFor(model => model.ObjectOfTypeB, 
       new SelectList(ViewBag.bs, "ID", "CategoryDescription"))

我假设在提交表单时,ObjectOfTypeB中的数据将被绑定到类型A的回发对象。但这不会发生。

任何人都可以解释我如何将特定字段的可能值列表传递给视图并让回发将值绑定到返回的对象上吗?

[错误打印屏幕] [1]

4 个答案:

答案 0 :(得分:1)

您的绑定不正确。如果您要填充ID媒体资源的ObjectOfTypeB属性,那么您的DropDownListFor应该绑定到model => model.ObjectOfTypeB.ID

如果您查看来源,如果您希望它在回发时自动填充该属性,那么您的来源应该类似于<select name="ObjectOfTypeB.ID">

在这种情况下,我可能会使用ViewModel(VM)来表示您的模型。你并不真正填写完整的对象B,因为B包含与所选ID相关的类别和描述 - 换句话说,这三个属性绑定在一起而不是单独填充。

我会做类似的事情:

class AViewModel
{
    public int ID {set;get;}

    public string MyObjectName {set; get;}

    public int IDofB { set; get; }
}

为了让您的生活更容易在A和AViewModel之间进行转换,请查看AutoMapper等工具。

答案 1 :(得分:0)

您必须再次填充ViewBag以将绑定返回到View。您可以创建一个方法来为您填充此ViewBag,并在get / post方法添加/编辑时使用它。尽量保持ViewModels(我想称之为InputModel)仅限原始类型(stringintdoublebool)换句话说,将B复杂类型更改为int。尝试这样的事情:

private void SetViewBagCombo(int selectedValue = 0)
{
   ViewBag.bs = new SelectList(getBobjects(), "Id", "CategoryDescription", selectedValue);
}

public ActionResult Create()
{
   SetViewBagCombo(); 
   return View();   
}

[HttpPost]
public ActionResult Create(A input)
{
   if (ModelState.IsValid)
   {
      // persist it
      return RedirectToAction("Index");
   }

   SetViewBagCombo(input.B.Id); 
   return View();   
}

在你的观点中:

@Html.DropDownListFor(model => model.IdOfB, (SelectList)ViewBag.bs, "Select...")

答案 2 :(得分:0)

  private IList getBobjects()
        {
        List<B> bs = new List<B>();
        bs.Add(new B() { ID = 1, CategoryNumber = 2, 
             CategoryDescription = "Config 1" });
        bs.Add(new B() { ID = 2, CategoryNumber = 3, 
             CategoryDescription = "Config 2" });
        return bs;
        }

    public IList<SelectListItem> GetDropdownlistItems()
    {
        IList<SelectListItem> ilSelectList = new List<SelectListItem>();

        IList objlist = getBobjects();
        foreach (object[] arrobject in objlist)
        {
            SelectListItem selectListItem = new SelectListItem();
            selectListItem.Value = arrobject[0].ToString();
            selectListItem.Text = arrobject[1].ToString();
            ilSelectList.Add(selectListItem);
        }

        return ilSelectList;
    }

    public ActionResult Create()
    {
        IList<SelectListItem> ilSelectListItems = GetDropdownlistItems();
        ViewBag.bs = ilSelectListItems;
        return View();
    } 

并在视野中:

@Html.DropDownList("bs", new SelectList(ViewBag.bs, "Text", "Value"))

希望这有帮助,谢谢。

答案 3 :(得分:0)

我为该复杂类类型模型

创建了一个viewmodel

为每个嵌套对象都有一个键,并且这些键使用了引用对象类型中的选择列表来显示文本。

之后在帖子后面我将viewmodel翻译回模型的类型