5

这个问题已经让我发疯了几个小时......

在我的域中,我有 2 个彼此相关的实体,Sku并且Item. 每个 sku 可以有许多项目。

public class Sku
{
    private readonly EntitySet<Item> items;
    public Sku()
    {
        items = new EntitySet<Item>(AttachItems, DetachItems);
    }
    public int SkuId { get; set; }
    public string LongDescription { get; set; }
    public EntitySet<Item> Items
    {
        get { return items; }
        set{ items.Assign(value);}
    }
    private void AttachItems(Item entity)
    {
        entity.Sku = this;
    }
    private static void DetachItems(Item entity)
    {
        entity.Sku = null;
    }
}

public class Item
{
    public Sku Sku { get; set; }
    public int ItemId { get; set; }
    public string Category { get; set; }
    public string Description { get; set; }
}

我正在构建一个页面,允许最终用户同时更新 sku 上的一些字段和每个项目上的一些字段。

<% using (Html.BeginForm("Save", "Merchant", FormMethod.Post, 
       new { enctype = "multipart/form-data" })) { %>       
<fieldset>
    <legend>Sku</legend>
    <p><label for="SkuId">SkuId:</label>
       <%= Html.TextBox("SkuId", Model.SkuId, 
           new{@readonly="readonly",onfocus="this.blur();"}) %></p>
    <p><label for="LongDescription">LongDescription:</label>
       <%= Html.TextBox("LongDescription", Model.LongDescription) %></p>
</fieldset>
<% for (int i = 0; i < Model.Items.Count; i++) { %>       
<fieldset>
    <legend>Item</legend>
    <p><label for="ItemId">ItemId:</label>
       <%= Html.TextBox(string.Format("items[{0}].{1}", i, "ItemId"), 
           Model.Items[i].ItemId, 
           new { @readonly = "readonly", onfocus = "this.blur();" })%></p>
    <p><label for="Category">Category:</label>
       <%= Html.TextBox(string.Format("items[{0}].{1}", i, "Category"), 
           Model.Items[i].Category)%></p>
    <p><label for="Description">Description:</label>
       <%= Html.TextBox(string.Format("items[{0}].{1}", i, "Description"), 
           Model.Items[i].Description)%></p>
</fieldset>
<%} // for-loop %>
    <p><input type="submit" value="Save" /></p>
<%} // form %> 

我有一些控制器代码可以通过同时接受 aSku和 an EntitySetofItem然后将其分配ItemsSku.

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Save(Sku sku, EntitySet<Item> items)
    {
        if (sku != null)
        {
            if (items != null)
            {
                sku.Items.Assign(items);
            }
        }

        // save Sku to repository ...
        // return Details view ...
    }

这行得通,但是我DefaultModelBinder注意到Item除了Sku. 绑定时,会调用Skusetter ,并且绑定器甚至会传入具有正确值的水合集合。但是,在调用 之后,就是。这就是为什么我必须重新分配控制器代码中的项目。我期待这些物品被活页夹转移到收藏品中。这应该消除每个项目的额外行程,因为可以删除我的控制器方法上的参数。为什么这不起作用?ItemsItemsitems.AssignItems.Count0Itemsitems

4

3 回答 3

1

您可能需要为此创建一个自定义模型绑定器?

于 2009-08-14T02:23:43.273 回答
1

希望我能正确理解您的问题...

您是否尝试过仅使用Sku类型的单个参数定义它,而不是使用 2 个参数定义您的Save操作?

然后,您需要重新定义类似于以下示例的项目 HTML 控件...

<%=
    Html.TextBox
    (
        string.Format("sku.Items[{0}].{1}", i, "ItemId"), 
        Model.Items[i].ItemId, 
        new { @readonly = "readonly", onfocus = "this.blur();" }
    )
%>


这样,您将直接在 Sku 对象本身中填充项目。


另一个潜在的解决方案是向您的 Item 类添加一个附加字段,例如...

Int32 SkuId { get; set; }

这样,您可以为视图中的每个项目定义一个附加隐藏字段,该字段将自动绑定到控制器返回的每个项目的 SkuId。

<%=
    Html.Hidden
    (
        string.Format("sku.Items[{0}].{1}", i, "SkuId"), 
        Model.Items[i].SkuId
    )
%>

然后,您可以独立于您的 Sku 对象更新您的项目集合。无论您采用哪种方式,这两个集合都必须明确告诉 Linq to SQL 无论如何都要更新 sku 和项目。

你也可以定义你自己的 binder 类,但在这种情况下,这可能比它的价值更多。只需遵循 ASP.NET MVC 约定,我认为您应该能够找到可以工作的东西,而不会觉得它是一个 hack。

于 2009-09-25T15:05:02.777 回答
0

我有一个类似的问题,即 EntitySets 没有在我的 ViewModel 中正确绑定。

我所做的是创建另一个名为 Mvc[YourEntitySetPropertyName] 的属性,作为通用列表,它围绕着 EntitySet 的私有字段:

public List<InvoiceLineItem> MvcInvoiceLineItemList
    {
        get { return _invoiceLineItemList.ToList(); }
        set { _invoiceLineItemList.AddRange(value); }
    }

然后我在视图标记上使用它而不是 EntitySet 属性。

无需传递控制器方法签名中的项目 - 只需在此时传递 Sku:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Save(Sku sku)
{
    if (sku != null)
    {
       // save Sku to repository ...
       // return Details view ...
    }

}
于 2009-10-01T14:42:33.710 回答