c# - ASP.NET Web Forms 4.5 模型绑定(bind),其中模型包含集合

标签 c# asp.net webforms model-binding

我正在尝试更新旧的 Web 窗体应用程序以使用 4.5 中添加的新模型绑定(bind)功能,类似于 MVC 绑定(bind)功能。

我在制作一个可编辑的 FormView 时遇到了麻烦,该 FormView 呈现一个包含简单成员的模型以及一个作为其他模型集合的成员。我需要用户能够编辑父对象的简单属性和子集合的属性。

问题在于,当代码尝试更新模型时,子集合 (ProductChoice.Extras) 在模型绑定(bind)后始终为 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 集合未绑定(bind)在 UpdateProduct 方法中。

最佳答案

深入研究 System.Web.ModelBinding 可以发现,CollectionModelBinder 期望传递到 FormValueProvider 的值的格式与 MVC 的格式相同,即:MyCollection[i]

public static string CreateIndexModelName(string parentName, string index)
{
    if (parentName.Length != 0)
    {
        return (parentName + "[" + index + "]");
    }
    return ("[" + index + "]");
}

不幸的是,您的中继器的元素名称将不符合该条件。

虽然肯定是非正统的,但您仍然可以通过编写非服务器文本框来实现此目的,然后为它们指定一个以数据列表命名容器开头的名称,后跟索引。得益于“Request.Unvalidated”(也在 4.5 中引入),您可以对这些数据进行数据绑定(bind),即使它不是由服务器端控件表示的。

关于c# - ASP.NET Web Forms 4.5 模型绑定(bind),其中模型包含集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21667583/

相关文章:

c# - 路由事件的TargetType

c# - Excel VBA 代码转换

c# - 如何读取 Excel 文件(仅标题)数据

asp.net - radGrid editForm userControl 内的异步回发

c# - 如何将数据从 Controller 传递到 ASP.net MVC 中查看?

asp.net - 为customvalidator设置errormessage?

html - 固定操作栏,考虑页脚

c# - 将文本和值都添加到 DropDownList (aspx)

c# - 通过 Automapper 将枚举属性映射到数组

html - 未最大化屏幕时布局损坏