我正在尝试更新旧的Web窗体应用程序,以使用4.5中添加的新模型绑定功能,类似于MVC绑定功能。
我在制作可编辑的FormView时遇到麻烦,该FormView可以显示一个包含简单成员以及一个包含其他模型的成员的模型。我需要用户能够编辑父对象的简单属性和子集合的属性。
问题在于,当代码试图更新模型时,子集合(ProductChoice.Extras
)在模型绑定之后始终为null。
这是我的模型:
[Serializable]
public class ProductChoice
{
public ProductChoice()
{
Extras = new List<ProductChoiceExtra>();
}
public int Quantity { get; set; }
public int ProductId { get; set; }
public List<ProductChoiceExtra> Extras { get; set; }
}
[Serializable]
public class ProductChoiceExtra
{
public int ExtraProductId { get; set; }
public string ExtraName { get; set; }
public int ExtraQuantity { get; set; }
}
而我的用户控制代码背后:
public partial class ProductDetails : System.Web.UI.UserControl
{
private Models.ProductChoice _productChoice;
protected void Page_Load(object sender, EventArgs e)
{
_productChoice = new Models.ProductChoice()
{
Quantity = 1,
ProductId = 1
};
_productChoice.Extras.Add(new Models.ProductChoiceExtra()
{
ExtraProductId = 101,
ExtraName = "coke",
ExtraQuantity = 1
});
_productChoice.Extras.Add(new Models.ProductChoiceExtra()
{
ExtraProductId = 104,
ExtraName = "sprite",
ExtraQuantity = 2
});
}
public Models.ProductChoice GetProduct()
{
return _productChoice;
}
public void UpdateProduct(Models.ProductChoice model)
{
/* model.Extras is always null here, it should contain two ProductChoiceExtra objects */
if (TryUpdateModel(_productChoice) == true)
{
}
}
}
我的控件标记:
<div id="selectOptions">
<asp:FormView runat="server" ID="fvProductSelection" DefaultMode="Edit"
ItemType="Models.ProductChoice"
SelectMethod="GetProduct"
UpdateMethod="UpdateProduct" >
<EditItemTemplate>
<asp:linkbutton id="UpdateButton" text="Update" commandname="Update" runat="server"/>
<asp:HiddenField runat="server" ID="ProductId" Value="<%# BindItem.ProductId %>" />
<asp:TextBox Text ="<%# BindItem.Quantity %>" ID="Quantity" runat="server" />
<asp:Repeater ID="Extras" ItemType="Models.ProductChoiceExtra" DataSource="<%# BindItem.Extras %>" runat="server">
<ItemTemplate>
<asp:HiddenField Value="<%# BindItem.ExtraProductId %>" ID="ExtraProductId" runat="server" />
<asp:Label Text="<%# BindItem.ExtraName %>" ID="Name" runat="server" />
<asp:TextBox Text="<%# BindItem.ExtraQuantity %>" ID="Quantity" runat="server" />
</ItemTemplate>
</asp:Repeater>
</EditItemTemplate>
</asp:FormView>
</div>
我尝试将
Extras
属性设置为BindingList
而不是List
,但没有任何区别,Extras
集合未绑定在UpdateProduct
方法中。 最佳答案
不幸的是,我不确切知道如何使用Web Forms来完成此操作,因此我不确定如何使用中继器来重现它,但是在MVC中,模型绑定器需要一个索引来重建列表。如果我不得不猜测这是如何在Web表单中完成的,那将类似于以下内容:
<div id="selectOptions">
<asp:FormView runat="server" ID="fvProductSelection" DefaultMode="Edit"
ItemType="Models.ProductChoice"
SelectMethod="GetProduct"
UpdateMethod="UpdateProduct" >
<EditItemTemplate>
<asp:linkbutton id="UpdateButton" text="Update" commandname="Update" runat="server"/>
<asp:HiddenField runat="server" ID="ProductId" Value="<%# BindItem.ProductId %>" />
<asp:TextBox Text ="<%# BindItem.Quantity %>" ID="Quantity" runat="server" />
<% for (int i = 0; i < BindItem.Extras.Count; i++)
{ %>
<asp:HiddenField Value="<%# BindItem.Extras[i].ExtraProductId %>" ID="ExtraProductId" runat="server" />
<asp:Label Text="<%# BindItem.Extras[i].ExtraName %>" ID="Name" runat="server" />
<asp:TextBox Text="<%# BindItem.Extras[i].ExtraQuantity %>" ID="Quantity" runat="server" />
<% } %>
</EditItemTemplate>
</asp:FormView>
</div>
注意,我用一个for循环替换了转发器,该循环使用用于访问每个Extra的索引遍历集合。这类似于我在ASP.NET MVC中需要执行的操作的方式。提交表单时,索引将与Web表单的其余部分一起发布,这允许模型绑定程序重构对象的有序列表。
我希望这能为您带来一定的帮助,请原谅我的任何错误,因为目前我没有Web表单项目可以对此进行测试。