我有一个复杂的类,它是viewmodel属性的一部分。我的viewmodel有一个wine类属性,wine类有一个名为CaseProductions的ICollection属性。 CaseProduction类也有几个属性。
在create GET事件中,NewWineViewModel被实例化,然后它运行GetCaseProductionDefaults并创建一个CaseProduction类列表,这些类具有一些默认值,但大部分都是空的。
现在,我最初使用razor做一个foreach语句,然后按照我想要的方式弹出我的表。但我已经看到,无法将这种类型的IEnumerable绑定回POST上的viewmodel。我试过用下面的,但没有骰子。
EditorFor(m => m.Wine.CaseProductions)
我真的在寻找有关处理这个问题的最佳方法的建议。每种葡萄酒都有一系列的caseproductions,我希望它能在视图模型中绑定回葡萄酒。他们是否可以通过某种方式在剃刀中编辑这些元素的ID以确保它们绑定?处理这个问题的最佳方法是什么?
视图模型:
public class NewWineViewModel
{
public Wine Wine { get; set; }
public VOAVIRequest VOAVIRequest { get; set; }
public bool IsRequest { get; set; }
public Dictionary<int, int> BottlesPerCase { get; set; }
public SelectList VarTypes { get; set; }
public SelectList Origins { get; set; }
public SelectList Apps { get; set; }
public SelectList Vintages { get; set; }
public SelectList Importers { get; set; }
}
案例制作类:
public class CaseProduction
{
public int CaseProductionID { get; set; }
public int WineID { get; set; }
public int CaseProductionSizeID { get; set; }
public int CaseCount { get; set; }
public int CountPerCase { get; set; }
public virtual CaseProductionSize CaseProductionSize { get; set; }
public virtual Wine Wine { get; set; }
}
获取默认案例制作:
public List<CaseProduction> GetCaseProductionDefaults(vfContext db)
{
//creates blank list of all formats
List<CaseProduction> cp = new List<CaseProduction>();
foreach (CaseProductionSize size in db.CaseProductionSizes)
{
int defaultBottlesPerCase = 1;
switch ((CaseProductionSizeEnum)size.CaseProductionSizeID)
{
case CaseProductionSizeEnum.s187ml:
defaultBottlesPerCase= 24;
break;
case CaseProductionSizeEnum.s375ml:
defaultBottlesPerCase = 12;
break;
case CaseProductionSizeEnum.s500ml:
defaultBottlesPerCase = 12;
break;
case CaseProductionSizeEnum.s750ml:
defaultBottlesPerCase = 12;
break;
default:
defaultBottlesPerCase = 1;
break;
}
cp.Add(new CaseProduction { CaseProductionSizeID = size.CaseProductionSizeID, CountPerCase = defaultBottlesPerCase, CaseProductionSize = size, WineID = this.Wine.WineID });
}
return cp;
}
我的案例制作表的剃刀代码:
@foreach (vf2.Models.CaseProduction cp in Model.Wine.CaseProductions)
{
<tr>
<td>@cp.CaseProductionSize.Name
</td>
<td>@Html.Raw(@Html.TextBoxFor(m => m.Wine.CaseProductions.Where(c => c.CaseProductionSizeID == cp.CaseProductionSizeID).First().CaseCount, new { @class = "caseCount", id = "txt" + cp.CaseProductionSize.Name }).ToString().Replace("CaseCount","txt" + cp.CaseProductionSize.Name))
</td>
<td>
@Html.DropDownListFor(m => m.Wine.CaseProductions.Where(c => c.CaseProductionSizeID == cp.CaseProductionSizeID).First().CountPerCase, new SelectList(Model.BottlesPerCase, "Key", "Value", cp.CountPerCase), new { @class = "countPerCase", id = "ddl" + cp.CaseProductionSize.Name, name = "ddl" + cp.CaseProductionSize.Name})
</td>
<td class="totalBottleCalc">
</td>
</tr>
}
我的caseproduction集合的实例化:
public ActionResult Create(int ID = 0, int VintUpID = 0)
{
NewWineViewModel nw = new NewWineViewModel();
nw.Wine.CaseProductions = nw.GetCaseProductionDefaults(db);
nw.BottlesPerCase = nw.GetBottlesPerCase(db);
答案 0 :(得分:0)
您必须在父模型构造函数中实例化嵌套列表和复杂模型。默认模型绑定程序不会实例化子类。
如果你这样做,那么你可以使用EditorFor(m =&gt; m.Wine.CaseProductions),并且你不需要你正在使用的复杂视图代码。
如果要自定义CaseProduction的呈现方式,则可以在〜/ Shared / EditorTemplates中创建CaseProduction.cshtml文件,它将使用此定义呈现集合中的每个项目(它将自动迭代集合)为你)。
此外,您不应在视图中执行linq查询。您的问题是,您将数据实体直接传递给视图。这是糟糕的设计。您需要创建一个仅包含呈现视图所需信息的ViewModel。然后,在将数据分配给View模型之前过滤数据。
答案 1 :(得分:0)
我认为模型绑定器没有拾取CaseProduction
个对象,因为它们看起来不像CaseProduction
个对象。
您已重命名CaseCount
,您的CaseProductionSize
没有ID(也不是CaseProduction
,而且它缺少多个属性。在您的循环中,您必须包含所有属性,并保留名称与您的POCO名称一致。否则模型绑定器将不知道它们是什么。如果需要,您可以将所有属性放在隐藏字段中。