C# 如何在MVC5中处理嵌套集合

C# 如何在MVC5中处理嵌套集合,c#,asp.net-mvc,asp.net-mvc-5,C#,Asp.net Mvc,Asp.net Mvc 5,我正在使用MVC5,我希望有一个编辑页面,允许从列表中选择项目,并为每个项目选择选项。我有一个这样的模型: public class TemplateEdit { public Guid TemplateId {get; set;} public string TemplateName {get; set;} public ICollection<MyOption> Options {get; set;} } public class MyOption {

我正在使用MVC5,我希望有一个编辑页面,允许从列表中选择项目,并为每个项目选择选项。我有一个这样的模型:

public class TemplateEdit
{
    public Guid TemplateId {get; set;}
    public string TemplateName {get; set;}
    public ICollection<MyOption> Options {get; set;}
}

public class MyOption
{
    public Guid MyOptionId {get; set;}
    public Guid TemplateId {get; set;}
    public string OptionName {get; set;}
    public bool Selected {get; set;}
    public ICollection<SubOption> SubOptions {get; set;}
}

public class SubOption
{
    public Guid SubOptionId {get; set;}
    public Guid MyOptionId {get; set;}
    public string SubOptionName {get; set;}
    public bool Selected {get; set;}
}
@model TemplateEdit
<div class="form-group col-md-12">
    @Html.ValidationSummary(false, "", new { @class = "text-danger" })
    @Html.HiddenFor(model => model.TemplateId)
</div>

<div class="form-group col-md-12">
    @Html.LabelForRequired(m => m.TemplateName, new {@class = "control-label"})
    @Html.TextBoxFor(m => m.TemplateName, new {@class = "form-control"})
</div>

<div class="col-md-12" style="overflow: auto; height: 350px;">
    @Html.Label("Options Selected")
    <div>
        @Html.EditorFor(m => m.Options);
    </div>
</div>
@model System.Collections.Generic.IEnumerable<SubOption>
@foreach(var option in Model)
{
    <div class="optionable">

       @Html.HiddenFor(m => option.SubOptionId)
       ...

    </div>
}
MyOption.cshtml
EditorTemplate中:

@model MyOption
<div class="optionable">

    @Html.HiddenFor(m => m.MyOptionId)
    @Html.HiddenFor(m => m.TemplateId)

    <div class="row">
        <div class="col-md-2">
            @Html.CheckBoxFor(model => model.Selected, new { @class = "form-control optionToggle" })
        </div>

        <div class="col-md-8">
            @Html.DisplayFor(model => model.OptionName, new { @class = "form-control" } )
        </div>
    </div>
    <div class="row options">
        @Html.EditorFor(m => m.SubOptions);
    </div>
</div>
@model SubOption
<div class="optionable">

    @Html.HiddenFor(m => m.SubOptionId)
    @Html.HiddenFor(m => m.MyOptionId)

    <div class="row">
        <div class="col-md-2">
            @Html.CheckBoxFor(model => model.Selected, new { @class = "form-control optionToggle" })
        </div>

        <div class="col-md-8">
            @Html.DisplayFor(model => model.SubOptionName, new { @class = "form-control" } )
        </div>
    </div>
</div>
我遇到的问题是,当我返回模型时,我没有得到子选项数据

注:

我找到的所有示例都是针对MVC3或更早版本的,并使用索引方法迭代集合。我会尝试这样做,但我正在使用ICollection进行收集。

检查控制器中的操作。如果要将viewmodel作为参数传递,则它应包含“子选项”集合

i、 e


子选项.cshtml
更改为如下所示:

public class TemplateEdit
{
    public Guid TemplateId {get; set;}
    public string TemplateName {get; set;}
    public ICollection<MyOption> Options {get; set;}
}

public class MyOption
{
    public Guid MyOptionId {get; set;}
    public Guid TemplateId {get; set;}
    public string OptionName {get; set;}
    public bool Selected {get; set;}
    public ICollection<SubOption> SubOptions {get; set;}
}

public class SubOption
{
    public Guid SubOptionId {get; set;}
    public Guid MyOptionId {get; set;}
    public string SubOptionName {get; set;}
    public bool Selected {get; set;}
}
@model TemplateEdit
<div class="form-group col-md-12">
    @Html.ValidationSummary(false, "", new { @class = "text-danger" })
    @Html.HiddenFor(model => model.TemplateId)
</div>

<div class="form-group col-md-12">
    @Html.LabelForRequired(m => m.TemplateName, new {@class = "control-label"})
    @Html.TextBoxFor(m => m.TemplateName, new {@class = "form-control"})
</div>

<div class="col-md-12" style="overflow: auto; height: 350px;">
    @Html.Label("Options Selected")
    <div>
        @Html.EditorFor(m => m.Options);
    </div>
</div>
@model System.Collections.Generic.IEnumerable<SubOption>
@foreach(var option in Model)
{
    <div class="optionable">

       @Html.HiddenFor(m => option.SubOptionId)
       ...

    </div>
}
@model System.Collections.Generic.IEnumerable
@foreach(模型中的var选项)
{
@Html.HiddenFor(m=>option.SubOptionId)
...
}

您正在将集合传递给EditorFor,因此您的模板也应使用集合而不是单个项。

选项正确返回,但子选项不正确吗?另外,您可以分享@Html.HiddenFor(m=>m.SubOptionId)在页面上实际呈现的内容吗?EditorTemplates应该在这里工作,只要在页面上呈现正确的名称,您是根本没有获得任何数据,还是只是缺少了
选项name
子选项name
属性?当我尝试这个方法时,这些是唯一缺少的,这是有意义的,因为它们没有
隐藏的
。您显示的代码可以正常工作。POST方法的签名是什么?您是否绝对确定集合中存在子选项数据?不要假设,要验证。另外,这不应该是
TemplateEdit.cshtml
而不是
template edit.cshtml
?除非模板编辑是顶层视图。这实际上是不必要的。当一个集合被传递到EditorFor()中时,MVC足够聪明,可以为每个集合呈现一个EditorTemplate。事实上,当以这种方式循环时,我经常看到当使用foreach回传模型时,模型绑定失败几乎总是错误的解决方案,并且不会生成正确的命名。此外,正如Loren提到的,这是不必要的。嗯,据我记忆所及,在我积极使用MVC时,这种方法对我很有效。同时,这也是一个可行的解决方案:然而,我不是MVC的专业人士,所以我可能仍然是错的。你能描述一下这种方法有什么问题吗?u人们请不要因此而贬低我。u为什么不呢?你知道规则。但你本可以回答这个问题。我还不确定这是否解决了OP的请求,所以我不想把它作为答案发布。谢谢你为我编辑我的答案。