C# 绑定包含嵌套对象的ViewModel类
我创建了一个类,它保存其他复杂类的对象 比如说C# 绑定包含嵌套对象的ViewModel类,c#,asp.net-mvc,selectlist,selectlistitem,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; }
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类型创建输入字段
在我的create函数中
// 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();
}
我假设在提交表单时,ObjectOfTypeB中的数据将绑定到类型A的post-back对象,但事实并非如此
有人能解释一下我如何将特定字段的可能值列表传递给视图,并让回发将该值绑定到返回的对象上吗
[Bug Print Screen][1]您的绑定不正确。如果您试图填充
ObjectOfTypeB
属性的ID
属性,那么您的DropDownListFor
应该绑定到model=>model.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之类的工具。您必须再次填充
视图包
,才能将绑定返回到视图
。您可以创建一个填充此ViewBag的方法,并在get/post方法add/edit上使用它。试着只使用基本类型(string
,int
,double
,bool
)来保持您的ViewModels
(我喜欢称为InputModel
),换句话说,将B复杂类型更改为aint
。试着这样做:
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...")
希望这有帮助,谢谢。我为这个复杂的类类型模型创建了一个viewmodel 每个嵌套对象都有一个键,这些键使用引用对象类型中的selectlist来显示文本
在这之后,我在回帖中将viewmodel转换回模型的类型。在回帖之后,您必须获取数据并再次绑定到您的模型。提交后,您将只获得choosen数据的id。我认为Felipes的答案是正确的,但在您的情况下,您必须设置ViewBag.bs=GetBobObjects();在用[HttpPost]属性标记的ActionResult中。我尝试了以下代码。我有一些错误的打印屏幕,如果你能检查出来的话。似乎它仍然没有约束力。(注意类的名称与上面写的不同)这是因为dropdown没有得到除null之外的项值。在getCategories()中,使用IList而不是List,并按照您编写的那样将其余部分保留在函数中。在getDropDownlitItems()函数中写入:IList objlist=getCategories();foreach(对象[]对象列表中的arObject){SelectListItem SelectListItem=new SelectListItem();SelectListItem.Value=arObject[0].ToString();SelectListItem.Text=arObject[1].ToString();ilSelectList.Add(SelectListItem);}并保持您所写的返回类型。
@Html.DropDownListFor(model => model.IdOfB, (SelectList)ViewBag.bs, "Select...")
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"))