Asp.net mvc 带有嵌套集合的ASP.NET MVC模型绑定问题

Asp.net mvc 带有嵌套集合的ASP.NET MVC模型绑定问题,asp.net-mvc,data-annotations,model-binding,mvc-editor-templates,Asp.net Mvc,Data Annotations,Model Binding,Mvc Editor Templates,我有一个包含选项列表的问题列表。他们的问题有一个类型字段,允许问题是单选按钮或检查表等 private void BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) { PropertyDescriptorCollection properties = GetModelProperties(controllerContext, binding

我有一个包含选项列表的问题列表。他们的问题有一个类型字段,允许问题是单选按钮或检查表等

    private void BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        PropertyDescriptorCollection properties = GetModelProperties(controllerContext, bindingContext);
        Predicate<string> propertyFilter = bindingContext.PropertyFilter;

        // Loop is a performance sensitive codepath so avoid using enumerators.
        for (int i = 0; i < properties.Count; i++)
        {
            PropertyDescriptor property = properties[i];
            if (ShouldUpdateProperty(property, propertyFilter))
            {
                BindProperty(controllerContext, bindingContext, property);
            }
        }
    }
我试图以这样一种方式创建视图,我将返回问题和选项。现在我不在乎别人的反应

    private void BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        PropertyDescriptorCollection properties = GetModelProperties(controllerContext, bindingContext);
        Predicate<string> propertyFilter = bindingContext.PropertyFilter;

        // Loop is a performance sensitive codepath so avoid using enumerators.
        for (int i = 0; i < properties.Count; i++)
        {
            PropertyDescriptor property = properties[i];
            if (ShouldUpdateProperty(property, propertyFilter))
            {
                BindProperty(controllerContext, bindingContext, property);
            }
        }
    }
据我所知,我正在遵循ASP.NET开箱即用模型绑定的规则,这些列表是在以下两个地方通过博客发布的

    private void BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        PropertyDescriptorCollection properties = GetModelProperties(controllerContext, bindingContext);
        Predicate<string> propertyFilter = bindingContext.PropertyFilter;

        // Loop is a performance sensitive codepath so avoid using enumerators.
        for (int i = 0; i < properties.Count; i++)
        {
            PropertyDescriptor property = properties[i];
            if (ShouldUpdateProperty(property, propertyFilter))
            {
                BindProperty(controllerContext, bindingContext, property);
            }
        }
    }
斯科特·汉斯曼的博客:
菲尔·哈克的博客:

    private void BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        PropertyDescriptorCollection properties = GetModelProperties(controllerContext, bindingContext);
        Predicate<string> propertyFilter = bindingContext.PropertyFilter;

        // Loop is a performance sensitive codepath so avoid using enumerators.
        for (int i = 0; i < properties.Count; i++)
        {
            PropertyDescriptor property = properties[i];
            if (ShouldUpdateProperty(property, propertyFilter))
            {
                BindProperty(controllerContext, bindingContext, property);
            }
        }
    }
是否可以使用开箱即用的模型活页夹执行我正在尝试执行的操作,或者是否需要实现我自己的自定义模型活页夹

    private void BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        PropertyDescriptorCollection properties = GetModelProperties(controllerContext, bindingContext);
        Predicate<string> propertyFilter = bindingContext.PropertyFilter;

        // Loop is a performance sensitive codepath so avoid using enumerators.
        for (int i = 0; i < properties.Count; i++)
        {
            PropertyDescriptor property = properties[i];
            if (ShouldUpdateProperty(property, propertyFilter))
            {
                BindProperty(controllerContext, bindingContext, property);
            }
        }
    }
如果我真的需要实现一个定制的模型绑定器,你能给我指出一些简单的例子或博客文章来说明如何实现它吗

    private void BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        PropertyDescriptorCollection properties = GetModelProperties(controllerContext, bindingContext);
        Predicate<string> propertyFilter = bindingContext.PropertyFilter;

        // Loop is a performance sensitive codepath so avoid using enumerators.
        for (int i = 0; i < properties.Count; i++)
        {
            PropertyDescriptor property = properties[i];
            if (ShouldUpdateProperty(property, propertyFilter))
            {
                BindProperty(controllerContext, bindingContext, property);
            }
        }
    }
最后,我想使用问题列表和响应列表在数据注释中编写一个自定义属性来验证模型(通过确保每个问题至少有一个答案),同时在客户机上使用不引人注目的验证

    private void BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        PropertyDescriptorCollection properties = GetModelProperties(controllerContext, bindingContext);
        Predicate<string> propertyFilter = bindingContext.PropertyFilter;

        // Loop is a performance sensitive codepath so avoid using enumerators.
        for (int i = 0; i < properties.Count; i++)
        {
            PropertyDescriptor property = properties[i];
            if (ShouldUpdateProperty(property, propertyFilter))
            {
                BindProperty(controllerContext, bindingContext, property);
            }
        }
    }
如果有更好的解决方案,我愿意接受

    private void BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        PropertyDescriptorCollection properties = GetModelProperties(controllerContext, bindingContext);
        Predicate<string> propertyFilter = bindingContext.PropertyFilter;

        // Loop is a performance sensitive codepath so avoid using enumerators.
        for (int i = 0; i < properties.Count; i++)
        {
            PropertyDescriptor property = properties[i];
            if (ShouldUpdateProperty(property, propertyFilter))
            {
                BindProperty(controllerContext, bindingContext, property);
            }
        }
    }
下面是一个人为的例子来说明我的问题

    private void BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        PropertyDescriptorCollection properties = GetModelProperties(controllerContext, bindingContext);
        Predicate<string> propertyFilter = bindingContext.PropertyFilter;

        // Loop is a performance sensitive codepath so avoid using enumerators.
        for (int i = 0; i < properties.Count; i++)
        {
            PropertyDescriptor property = properties[i];
            if (ShouldUpdateProperty(property, propertyFilter))
            {
                BindProperty(controllerContext, bindingContext, property);
            }
        }
    }
视图模型:

public class Questionnaire
{
    private List<QuestionResponse> _questions;

    [UIHint("QuestionResponse")]
    public List<QuestionResponse> Questions
    {
        get { return _questions ?? (_questions = new List<QuestionResponse>()); }
        set { _questions = value; }
    }

    public List<int> Responses;
}
public class QuestionResponse
{
    public int QuestionId;

    public string QuestionType;

    public string QuestionCode;

    public string QuestionName;

    public string OpenResponse;

    public List<QuestionOptions> Options;
}

public class QuestionOptions
{
    public int OptionId;

    public string OptionType;

    public string OptionName;

    public string OptionDescription;

    public string OptionResponse;

    public bool Selected;

}
    [HttpGet]
    public ActionResult Questionnaire()
    {
        #region HardCodedDataz
        var questions = new List<QuestionResponse>
        {
            new QuestionResponse
            {
                QuestionId = 1,
                OpenResponse = null,
                QuestionCode = "1",
                QuestionName = "What kind of movies do you like?",
                QuestionType = "Checklist",
                Options = new List<QuestionOptions>
                {
                    new QuestionOptions
                    {
                        OptionDescription = "Horror",
                        OptionId = 1,
                        OptionName = "Horror",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Family",
                        OptionId = 2,
                        OptionName = "Family",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Comedy",
                        OptionId = 3,
                        OptionName = "Comedy",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Adventure",
                        OptionId = 4,
                        OptionName = "Adventure",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Drama",
                        OptionId = 5,
                        OptionName = "Drama",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false
                    }
                }
            },
            new QuestionResponse()
            {
                QuestionId = 2,
                OpenResponse = null,
                QuestionCode = "2",
                QuestionName = "Which university did you attend in your first year of college?", 
                QuestionType = "RadioButton",
                Options = new List<QuestionOptions>
                {
                    new QuestionOptions()
                    {
                        OptionDescription = "Cornell",
                        OptionId = 1,
                        OptionName = "Cornell",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false 
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Columbia",
                        OptionId = 2,
                        OptionName = "Columbia",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false 
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Harvard",
                        OptionId = 3,
                        OptionName = "Harvard",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false 
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Yale",
                        OptionId = 4,
                        OptionName = "Yale",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false 
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Princeton",
                        OptionId = 5,
                        OptionName = "Princeton",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false 
                    }
                }
            }
        };
        #endregion

        var model = new Questionnaire()
        {
            Questions = questions,
            Responses = new List<int>()
        };

        return PartialView(model);
    }

    [HttpPost]
    public JsonResult Questionnaire(List<QuestionResponse> questions, List<int> responses)
    {
        return Json(new
        {
            success = "some success message",
            error = "some error message"
        });
    }
@using TestApplication.Models
@model  Questionnaire

@using (Html.BeginForm("Questionnaire", "Home", FormMethod.Post))
{
    <div>
        @Html.EditorFor(m => m.Questions)
    </div>
    <div>
        <button type="submit">Save</button>
    </div>
}
    private void BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        PropertyDescriptorCollection properties = GetModelProperties(controllerContext, bindingContext);
        Predicate<string> propertyFilter = bindingContext.PropertyFilter;

        // Loop is a performance sensitive codepath so avoid using enumerators.
        for (int i = 0; i < properties.Count; i++)
        {
            PropertyDescriptor property = properties[i];
            if (ShouldUpdateProperty(property, propertyFilter))
            {
                BindProperty(controllerContext, bindingContext, property);
            }
        }
    }
公共课堂调查问卷
{
私人列表问题;
[UIHint(“问题回答”)]
公开问题清单
{
获取{return}questions???(_questions=newlist());}
设置{u questions=value;}
}
公众名单答复;
}
型号:

public class Questionnaire
{
    private List<QuestionResponse> _questions;

    [UIHint("QuestionResponse")]
    public List<QuestionResponse> Questions
    {
        get { return _questions ?? (_questions = new List<QuestionResponse>()); }
        set { _questions = value; }
    }

    public List<int> Responses;
}
public class QuestionResponse
{
    public int QuestionId;

    public string QuestionType;

    public string QuestionCode;

    public string QuestionName;

    public string OpenResponse;

    public List<QuestionOptions> Options;
}

public class QuestionOptions
{
    public int OptionId;

    public string OptionType;

    public string OptionName;

    public string OptionDescription;

    public string OptionResponse;

    public bool Selected;

}
    [HttpGet]
    public ActionResult Questionnaire()
    {
        #region HardCodedDataz
        var questions = new List<QuestionResponse>
        {
            new QuestionResponse
            {
                QuestionId = 1,
                OpenResponse = null,
                QuestionCode = "1",
                QuestionName = "What kind of movies do you like?",
                QuestionType = "Checklist",
                Options = new List<QuestionOptions>
                {
                    new QuestionOptions
                    {
                        OptionDescription = "Horror",
                        OptionId = 1,
                        OptionName = "Horror",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Family",
                        OptionId = 2,
                        OptionName = "Family",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Comedy",
                        OptionId = 3,
                        OptionName = "Comedy",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Adventure",
                        OptionId = 4,
                        OptionName = "Adventure",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Drama",
                        OptionId = 5,
                        OptionName = "Drama",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false
                    }
                }
            },
            new QuestionResponse()
            {
                QuestionId = 2,
                OpenResponse = null,
                QuestionCode = "2",
                QuestionName = "Which university did you attend in your first year of college?", 
                QuestionType = "RadioButton",
                Options = new List<QuestionOptions>
                {
                    new QuestionOptions()
                    {
                        OptionDescription = "Cornell",
                        OptionId = 1,
                        OptionName = "Cornell",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false 
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Columbia",
                        OptionId = 2,
                        OptionName = "Columbia",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false 
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Harvard",
                        OptionId = 3,
                        OptionName = "Harvard",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false 
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Yale",
                        OptionId = 4,
                        OptionName = "Yale",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false 
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Princeton",
                        OptionId = 5,
                        OptionName = "Princeton",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false 
                    }
                }
            }
        };
        #endregion

        var model = new Questionnaire()
        {
            Questions = questions,
            Responses = new List<int>()
        };

        return PartialView(model);
    }

    [HttpPost]
    public JsonResult Questionnaire(List<QuestionResponse> questions, List<int> responses)
    {
        return Json(new
        {
            success = "some success message",
            error = "some error message"
        });
    }
@using TestApplication.Models
@model  Questionnaire

@using (Html.BeginForm("Questionnaire", "Home", FormMethod.Post))
{
    <div>
        @Html.EditorFor(m => m.Questions)
    </div>
    <div>
        <button type="submit">Save</button>
    </div>
}
    private void BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        PropertyDescriptorCollection properties = GetModelProperties(controllerContext, bindingContext);
        Predicate<string> propertyFilter = bindingContext.PropertyFilter;

        // Loop is a performance sensitive codepath so avoid using enumerators.
        for (int i = 0; i < properties.Count; i++)
        {
            PropertyDescriptor property = properties[i];
            if (ShouldUpdateProperty(property, propertyFilter))
            {
                BindProperty(controllerContext, bindingContext, property);
            }
        }
    }
公共类问题回答
{
公共问题ID;
公共字符串类型;
公共字符串查询码;
公共字符串名称;
公共字符串OpenResponse;
公开列表选项;
}
公共类问题选项
{
公共int选项ID;
公共字符串OptionType;
公共字符串OptionName;
公共字符串选项说明;
公共字符串OptionResponse;
选择公共图书馆;
}
控制器方法:

public class Questionnaire
{
    private List<QuestionResponse> _questions;

    [UIHint("QuestionResponse")]
    public List<QuestionResponse> Questions
    {
        get { return _questions ?? (_questions = new List<QuestionResponse>()); }
        set { _questions = value; }
    }

    public List<int> Responses;
}
public class QuestionResponse
{
    public int QuestionId;

    public string QuestionType;

    public string QuestionCode;

    public string QuestionName;

    public string OpenResponse;

    public List<QuestionOptions> Options;
}

public class QuestionOptions
{
    public int OptionId;

    public string OptionType;

    public string OptionName;

    public string OptionDescription;

    public string OptionResponse;

    public bool Selected;

}
    [HttpGet]
    public ActionResult Questionnaire()
    {
        #region HardCodedDataz
        var questions = new List<QuestionResponse>
        {
            new QuestionResponse
            {
                QuestionId = 1,
                OpenResponse = null,
                QuestionCode = "1",
                QuestionName = "What kind of movies do you like?",
                QuestionType = "Checklist",
                Options = new List<QuestionOptions>
                {
                    new QuestionOptions
                    {
                        OptionDescription = "Horror",
                        OptionId = 1,
                        OptionName = "Horror",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Family",
                        OptionId = 2,
                        OptionName = "Family",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Comedy",
                        OptionId = 3,
                        OptionName = "Comedy",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Adventure",
                        OptionId = 4,
                        OptionName = "Adventure",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Drama",
                        OptionId = 5,
                        OptionName = "Drama",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false
                    }
                }
            },
            new QuestionResponse()
            {
                QuestionId = 2,
                OpenResponse = null,
                QuestionCode = "2",
                QuestionName = "Which university did you attend in your first year of college?", 
                QuestionType = "RadioButton",
                Options = new List<QuestionOptions>
                {
                    new QuestionOptions()
                    {
                        OptionDescription = "Cornell",
                        OptionId = 1,
                        OptionName = "Cornell",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false 
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Columbia",
                        OptionId = 2,
                        OptionName = "Columbia",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false 
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Harvard",
                        OptionId = 3,
                        OptionName = "Harvard",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false 
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Yale",
                        OptionId = 4,
                        OptionName = "Yale",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false 
                    },
                    new QuestionOptions()
                    {
                        OptionDescription = "Princeton",
                        OptionId = 5,
                        OptionName = "Princeton",
                        OptionResponse = null,
                        OptionType = "boolean",
                        Selected = false 
                    }
                }
            }
        };
        #endregion

        var model = new Questionnaire()
        {
            Questions = questions,
            Responses = new List<int>()
        };

        return PartialView(model);
    }

    [HttpPost]
    public JsonResult Questionnaire(List<QuestionResponse> questions, List<int> responses)
    {
        return Json(new
        {
            success = "some success message",
            error = "some error message"
        });
    }
@using TestApplication.Models
@model  Questionnaire

@using (Html.BeginForm("Questionnaire", "Home", FormMethod.Post))
{
    <div>
        @Html.EditorFor(m => m.Questions)
    </div>
    <div>
        <button type="submit">Save</button>
    </div>
}
    private void BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        PropertyDescriptorCollection properties = GetModelProperties(controllerContext, bindingContext);
        Predicate<string> propertyFilter = bindingContext.PropertyFilter;

        // Loop is a performance sensitive codepath so avoid using enumerators.
        for (int i = 0; i < properties.Count; i++)
        {
            PropertyDescriptor property = properties[i];
            if (ShouldUpdateProperty(property, propertyFilter))
            {
                BindProperty(controllerContext, bindingContext, property);
            }
        }
    }
[HttpGet]
公众行动结果问卷()
{
#哈达兹地区
var问题=新列表
{
新问题解答
{
问题ID=1,
OpenResponse=null,
QuestionCode=“1”,
QuestionName=“你喜欢什么类型的电影?”,
QuestionType=“检查表”,
选项=新列表
{
新问题选项
{
OptionDescription=“恐怖”,
OptionId=1,
OptionName=“恐怖”,
OptionResponse=null,
OptionType=“boolean”,
所选=错误
},
新问题选项()
{
OptionDescription=“家庭”,
OptionId=2,
OptionName=“家庭”,
OptionResponse=null,
OptionType=“boolean”,
所选=错误
},
新问题选项()
{
OptionDescription=“喜剧”,
选项ID=3,
OptionName=“喜剧”,
OptionResponse=null,
OptionType=“boolean”,
所选=错误
},
新问题选项()
{
OptionDescription=“冒险”,
选项ID=4,
OptionName=“冒险”,
OptionResponse=null,
OptionType=“boolean”,
所选=错误
},
新问题选项()
{
OptionDescription=“戏剧”,
选项ID=5,
OptionName=“戏剧”,
OptionResponse=null,
OptionType=“boolean”,
所选=错误
}
}
},
新问题回答()
{
问题ID=2,
OpenResponse=null,
QuestionCode=“2”,
问题名称=“你在大学一年级上的是哪所大学?”,
QuestionType=“RadioButton”,
选项=新列表
{
新问题选项()
{
OptionDescription=“康奈尔”,
OptionId=1,
OptionName=“康奈尔”,
OptionResponse=null,
OptionType=“boolean”,
所选=错误
},
新问题选项()
{
OptionDescription=“哥伦比亚”,
OptionId=2,
OptionName=“哥伦比亚”,
OptionResponse=null,
OptionType=“boolean”,
所选=错误
},
新问题选项()
{
OptionDescription=“哈佛”,
选项ID=3,
OptionName=“哈佛”,
OptionResponse=null,
OptionType=“boolean”,
所选=错误
},
新问题选项()
{
OptionDescription=“耶鲁”,
选项ID=4,