简体   繁体   English

自定义模型活页夹,用于儿童收藏

[英]Custom model binder for child collection

I've searched high and low so hopefully someone can help me. 我已经搜寻过很多东西,希望有人可以帮助我。 I have a class: 我有一节课:

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

I have a controller method: 我有一个控制器方法:

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

I want to bind to the collection. 我想绑定到收藏夹。 I realize I will only get the IDs but I will deal with that in my controller. 我意识到我只会得到ID,但会在控制器中处理它。 I just need to be able to flip through the collection of IDs. 我只需要能够浏览ID的集合即可。 I started writing a model binder: 我开始编写模型活页夹:

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???
            }
}

So how do I build the collection of Toys from the values passed into my method? 那么如何从传递给我方法的值构建Toys集合呢? Thanks! 谢谢!

EDIT: Looks like I couldn't post this answer to my own question so I'll just edit my post. 编辑:看来我无法发布此答案对我自己的问题,所以我将只编辑我的帖子。 looks like all you have to do is parse out the data and add it to the model like so: 看起来您需要做的就是解析数据并将其添加到模型中,如下所示:

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

You shouldn't need a custom model binder for this. 您不需要为此定制模型绑定器。

Refer to this post by Phil Haack for the full implementation, but the basic idea is that for each item in the collection, you make a form field that follows the following naming convention: 请参阅Phil Haack的这篇文章以获得完整的实现,但基本思路是,对于集合中的每个项目,您创建一个遵循以下命名约定的表单字段:

Toys[index].<FieldName>

So, for example, if you wanted to bind 3 Toy objects: 因此,例如,如果要绑定3个Toy对象:

<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" />

The important part is that all index values are accounted for and no indexes are skipped. 重要的是要考虑所有索引值,不要跳过任何索引。 For example, if you have a form value Toys[1].<FieldName> you must also have a Toys[0].<FieldName> value. 例如,如果您有一个格式值Toys[1].<FieldName>必须具有一个Toys[0].<FieldName>值。

All this being said, depending on what exactly you need to accomplish it may be easier to simply bind to a collection of Ids rather than whole objects. 所有这些都说,取决于你需要完成什么,它可能更容易简单地绑定到一组ID而不是整个对象。 You can let your controller action translate the Ids to actual models. 您可以让控制器操作将ID转换为实际模型。

If you prefer the simpler, Id-only approach, all you need to do is make a string/int/guid (whatever your id is) collection object in your request model and then create 1 or more fields all having the same name for each Id value. 如果您更喜欢更简单的Id-only方法,那么您需要做的就是在请求模型中创建一个字符串/ int / guid(无论您的id是什么)集合对象,然后创建一个或多个字段,每个字段都具有相同的名称 。 Id值。 The default model binder will automatically handle creating the collection from the values in the request. 默认模型绑定器将自动处理从请求中的值创建集合。

Building on the above answer for n amount of toys, you must use a for loop to index correctly, like so: 在以上答案中给出n个玩具的基础上,必须使用for循环正确索引,如下所示:

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

Then default model binding will auto-bind the collection on post. 然后默认模型绑定将自动绑定post上的集合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM