同一页面上的ASP.NET MVC模型相关实体
-
16-09-2019 - |
题
这个问题使我疯狂了几个小时...
在我的域中,我有两个彼此相关的实体 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 %>
我有一些控制器代码,可以通过接受 Sku
和 EntitySet
的 Item
然后分配 Items
到 Sku
.
[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
. 。当。。。的时候 Sku
被绑定,设置器 Items
被称为,粘合剂甚至可以通过 Items
收集正确的值。但是,在打电话后 items.Assign
, Items.Count
是 0
. 。这就是为什么我必须在控制器代码中重新分配项目。我期望将这些物品转移到 Items
粘合剂收集。这应该消除每项额外的旅行,因为 items
可以删除我的控制器方法上的参数。为什么这不起作用?
解决方案
您可能需要为此创建自定义模型粘合剂?
其他提示
希望我能正确理解您的问题...
而不是定义你的 节省 使用2个参数的操作,您是否尝试过仅使用单个参数定义它, sku?
然后,您将要重新定义类似于以下示例的项目HTML控件...
<%=
Html.TextBox
(
string.Format("sku.Items[{0}].{1}", i, "ItemId"),
Model.Items[i].ItemId,
new { @readonly = "readonly", onfocus = "this.blur();" }
)
%>
这样,您将直接在SKU对象本身中填充项目。
另一个潜在的解决方案是在您的项目类中添加一个其他字段,例如...
Int32 SkuId { get; set; }
这样,您可以为视图中的每个项目定义一个附加的隐藏字段,该字段将自动限制在控制器上的每个项目的skuid中。
<%=
Html.Hidden
(
string.Format("sku.Items[{0}].{1}", i, "SkuId"),
Model.Items[i].SkuId
)
%>
然后,您可以独立于SKU对象更新项目集合。无论您走哪种方式,这两个集合都必须明确告诉Linq到SQL,以更新SKU和项目。
您也可以定义自己的活页夹课程,但这可能比在这种情况下还要多。只需遵循ASP.NET MVC惯例,我认为您应该能够找到可以不觉得这是黑客的东西。
我也有一个类似的问题,即实体组合在我的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 ...
}
}