C# 当ListBox为空时,将永远不会调用该属性的setter

C# 当ListBox为空时,将永远不会调用该属性的setter,c#,asp.net-mvc,C#,Asp.net Mvc,我的财产如下: [DisplayName("Children")] public List<long> ChildrenIds { get { return SelectedGroup.Children.Select(x => x.Id).ToList(); } set { foreach (long groupId in value) {

我的财产如下:

    [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);
                }
            }
        }
    }

但是,当我取消选中上述
列表框中的所有项时,将永远不会调用此属性的setter,因此这些项永远不会被删除。。。确保删除所有项目的最佳方法是什么?

如果未选择任何项目,则不会从浏览器中发布数据,并且ASP.NET MVC模型绑定没有可设置的值

换句话说,模型绑定器说:“我没有要设置的值,所以我调用setter没有意义”,而您希望它说:“我没有要设置的值,但无论如何,我将使用空列表调用Serj的setter”

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

我建议你

1) 介绍类似MyForm类的内容,如下所示:

public class MyForm 
{ 
  public IEnumerable<int> ChildrenIds { get;set; }
}
4) 最后,对于您的操作方法,您可以将模型绑定到MyForm:

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

这将使您能够更清晰地将HTTP关注点与业务关注点分离。

该setter中有很多内容。你认为你可以使用一个更简单的setter来重现这种行为吗?我在setter中添加了一个断点,它在ListBox为空时从不被调用,调用得很好,并且在ListBox为非空时做它应该做的事情……我会给你答案,因为你帮我找到了解决方案,但是我必须说,你提出的解决方案是让我写一些相当难看的代码。。。我想我保持了我的模型的原样,将getter/setter更改为您拥有的方式,但是在我的模型的Save方法中编写setter代码…很高兴我能提供帮助:-)。我想您会发现,随着您的应用程序和用户交互变得越来越复杂,我的方法比您的方法扩展得更好。
public class MyViewModel 
{
  public MyViewModel(Data somedata)
  {
    /* populate Options */
  }

  public IEnumerable<SelectListItem> Options { get; set; }
  public MyForm Form { get; set; }
}
@Html.ListBoxFor(m => m.Form.ChildrenIds, Model.Options)
public ActionResult MyMethod(MyForm form)
{
  /* inspect POSTed form.ChildrenIds, add/remove from domain model etc. as you see fit */
}