0

我有一个属性如下:

    [DisplayName("Children")]
    public List<long> ChildrenIds
    {
        get { return SelectedGroup.Children.Select(x => x.Id).ToList(); }
        set
        {
            foreach (long groupId in value)
            {
                if (groupId != 0 && !SelectedGroup.Children.Select(x => x.Id).Contains(groupId))
                {
                    var group = FactoryTools.Factory.Get<GroupLookup>(groupId);

                    if (group != null) SelectedGroup.AddChild(group);
                }
            }

            var childrenLooper = SelectedGroup.Children.ToList();
            foreach (var group in childrenLooper)
            {
                if (group.Id != 0 && !value.Contains(group.Id))
                {
                    SelectedGroup.Children.Remove(group);
                }
            }
        }
    }

当我在我的标准中选择了至少 1 个孩子时,这很有效Razor Listbox

    <div class="oneThird">
        @Html.LabelFor(x => x.ChildrenIds)
        @Html.ListBoxFor(x => x.ChildrenIds, ListHelper.GetGroupsMinusSelf(Model.SelectedGroup))
        @Html.ValidationMessageFor(x => x.ChildrenIds)
    </div>

但是,当我取消选择上面的所有项目时ListBox,该属性的设置器永远不会被调用,因此这些项目永远不会被删除......确保所有项目都被删除的最佳方法是什么?

4

1 回答 1

2

当没有选择任何项目时,没有从浏览器发布的数据,并且 ASP.NET MVC 模型绑定没有要设置的值。

换句话说,模型绑定器说:“我没有要设置的值,所以我调用 setter 没有意义”,而您期望它说:“我没有要设置的值,但是无论如何,我都会用一个空列表来调用 Serj 的二传手”。

但是,这里真正的问题是,您正在推动模型绑定超出其设计目的。模型绑定只是应该将 HTTP 请求中数据的字符串表示形式转换为强类型数据。因此,您绑定到的模型应该表示 HTML 表单或类似简单的东西(是的,我知道 Microsoft 吹嘘您可以开箱即用地建模绑定到复杂对象,但这仅适用于最简单的情况,TBH )。数据被强类型化后,在您的操作方法(或业务对象、服务、帮助程序或其他)中进行数据处理。

我建议你

1)引入类似 MyForm 类的东西,如下所示:

public class MyForm 
{ 
  public IEnumerable<int> ChildrenIds { get;set; }
}

2)像这样引入一个视图模型:

public class MyViewModel 
{
  public MyViewModel(Data somedata)
  {
    /* populate Options */
  }

  public IEnumerable<SelectListItem> Options { get; set; }
  public MyForm Form { get; set; }
}

3)在您的视图中使用此模型:

@Html.ListBoxFor(m => m.Form.ChildrenIds, Model.Options)

4)最后,对于您的操作方法,您将模型绑定到 MyForm:

public ActionResult MyMethod(MyForm form)
{
  /* inspect POSTed form.ChildrenIds, add/remove from domain model etc. as you see fit */
}

这将使您更清晰地将 HTTP 关注点与业务关注点区分开来。

于 2013-07-30T21:49:47.997 回答