【问题标题】:Custom model binder for child collection用于子集合的自定义模型绑定器
【发布时间】:2011-11-10 20:59:23
【问题描述】:

我已经搜索了高低,希望有人可以帮助我。我有一堂课:

public class Person
{
    public string Name { get; set; }
    public ICollection<Toys> { get; set; }
}

我有一个控制器方法:

public ActionResult Update(Person toycollector)
{
....
}

我想绑定到集合。我意识到我只会得到 ID,但我会在我的控制器中处理它。我只需要能够翻阅 ID 的集合。我开始编写模型活页夹:

public class CustomModelBinder : DefaultModelBinder
    {
        protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
        {
            if (propertyDescriptor.PropertyType == typeof(ICollection<Toys>))
            {
                //What do I do here???
            }
}

那么,如何根据传递给我的方法的值构建玩具集合?谢谢!

编辑: 看起来我无法将这个答案发布到我自己的问题上,所以我将编辑我的帖子。看起来您所要做的就是解析数据并将其添加到模型中,如下所示:

if (propertyDescriptor.PropertyType == typeof(ICollection)) {

            var incomingData = bindingContext.ValueProvider.GetValue("Edit." + propertyDescriptor.Name + "[]");
            if (incomingData != null)
            {
                ICollection<Toy> toys = new List<Toy>();
                string[] ids = incomingData.AttemptedValue.Split(',');
                foreach (string id in ids)
                {
                    int toyId = int.Parse(id);
                    toys.Add(new Toy() { ToyID = toyId });
                }
                var model = bindingContext.Model as Person;
                model.Toys = toys;
            }
            return;
        }

【问题讨论】:

  • 您现在可以尝试添加答案吗?

标签: c# asp.net asp.net-mvc asp.net-mvc-3 asp.net-mvc-2


【解决方案1】:

您不需要为此使用自定义模型绑定器。

完整实现请参考this post by Phil Haack,但基本思想是为集合中的每个项目创建一个遵循以下命名约定的表单字段:

Toys[index].<FieldName>

因此,例如,如果您想绑定 3 个玩具对象:

<input type="hidden" name="Toys[0].Id" value="1" />
<input type="hidden" name="Toys[1].Id" value="2" />
<input type="hidden" name="Toys[2].Id" value="3" />

重要的部分是所有索引值都被考虑在内,并且没有跳过任何索引。例如,如果您有一个表单值 Toys[1].&lt;FieldName&gt;,那么您必须也有一个 Toys[0].&lt;FieldName&gt; 值。

说了这么多,具体取决于您需要完成什么,简单地绑定到 Id 集合而不是整个对象可能更容易。您可以让您的控制器操作将 ID 转换为实际模型。

如果您更喜欢更简单、仅 ID 的方法,您只需在请求模型中创建一个 string/int/guid(无论您的 id 是什么)集合对象,然后创建 1 个或多个字段 all每个 Id 值具有相同的名称。默认模型绑定器将自动处理根据请求中的值创建集合。

【讨论】:

    【解决方案2】:

    在上述 n 数量玩具的答案的基础上,您必须使用 for 循环正确索引,如下所示:

    @for(var i = 0; i < Model.Toys.Count; i++)
    {
        @Html.HiddenFor(m => m.Toys[i].Id)
    }
    

    然后默认模型绑定会在发布时自动绑定集合。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-31
      • 1970-01-01
      • 2014-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多