代码之家  ›  专栏  ›  技术社区  ›  Derek

保存时的模型绑定未返回嵌套对象的完整列表,最多返回一个

  •  0
  • Derek  · 技术社区  · 7 年前

    保存时的模型绑定未返回嵌套对象的完整列表,最多返回一个

    为了理解EditorTemplates,这里有一个简单的示例,目前还不起作用。模型没有返回完整的IList 对于项,它似乎每次返回1个对象,而在我的示例中应该有2个。

    编辑ModelA时,示例如下:

    - Name: Model A
        List of Model Bs:
            - Name: Model B1
                List of Model Cs:
                    - Name: Model C1
                    - Name: Model C2
            - Name: Model B2
    

    该列表在编辑过程中正确显示,但保存后,一些信息“丢失”,补充道 (not found) 在下面

    - Name: Model A (in Model)
        List of Model Bs:
            - Name: Model B1 (in Model)
                List of Model Cs:
                    - Name: Model C1 (in Model)
                    - Name: Model C2 (not found)
            - Name: Model B2 (not found)
    

    基本上,保存时,模型不会从列表中返回任何多个对象。

    课程:

    基本对象:

    public class BaseObject
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Key]
        public Guid Oid { get; set; }
    
    }
    

    public class ModelA : BaseObject
    {
        public string Name { get; set; }
        public virtual IList<ModelB> ModelBs { get; set; }
    }
    
    public class ModelB : BaseObject
    {
        public string Name { get; set; }
    
        public Guid? ModelAID { get; set; }
    
        [ForeignKey("ModelAID")]
        public virtual ModelA ModelA { get; set; }
    
        public virtual IList<ModelC> ModelCs { get; set; }
    }
    
    public class ModelC : BaseObject
    {
        public string Name { get; set; }
    
        public Guid? ModelBID { get; set; }
    
        [ForeignKey("ModelBID")]
        public virtual ModelB ModelB { get; set; }
    }
    

    ModelA的基本控制器,以下是编辑:

    public ActionResult Edit(Guid? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        ModelA modelA = db.ModelAs.Find(id);
        if (modelA == null)
        {
            return HttpNotFound();
        }
        return View(modelA);
    }
    
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(ModelA modelA)
    //Removed: [Bind(Include = "Oid,Name,DateCreated,DateUpdated,DateDeleted,IsDeleted")] 
    {
        if (ModelState.IsValid) //Break point to review "modelA"
        {
            db.Entry(modelA).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(modelA);
    }
    

    意见:

    编辑cshtml(适用于ModelA):

    @model x.Models.Nesting.ModelA
    
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
        @Html.EditorForModel(Model)
    }
    

    视图/共享/编辑模板中的视图:

    ModelA。cshtml:

    @model x.Models.Nesting.ModelA
    
    <div class="form-horizontal">
        <h4>ModelA</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.Oid)
    
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>
    
        <div class="form-group">
            @Html.LabelFor(model => model.ModelBs, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
    
                @Html.EditorFor(model => model.ModelBs)
    
                @* Tried the code below as well *@
                @*
                @for (var i = 0; i < Model.ModelBs.Count(); i++)
                {
                    @Html.EditorFor(m => m.ModelBs[i])
                }
                *@
    
            </div>
        </div>
    
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
    

    模型B。cshtml:

    @model x.Models.Nesting.ModelB
    @using (Html.BeginForm())
    {
        <div class="form-horizontal">
            @Html.ValidationSummary(true, "", new { @class = "text-danger" })
            @Html.HiddenFor(model => model.Oid)
            @Html.HiddenFor(model => model.ModelAID)
    
            <div class="form-group">
                @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
                </div>
            </div>
    
            <div class="form-group">
                @Html.LabelFor(model => model.ModelCs, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
    
                    @Html.EditorFor(model => model.ModelCs)
    
                    @* Tried the code below as well *@
                    @*
                    @foreach(var item in Model.ModelCs)
                    {
                        @Html.EditorFor(x => item)
                    }
                    *@
    
                </div>
            </div>
    
        </div>
    }
    

    模型C。cshtml:

    @model x.Models.Nesting.ModelC
    
    @using (Html.BeginForm())
    {
        <div class="form-horizontal">
            @Html.ValidationSummary(true, "", new { @class = "text-danger" })
            @Html.HiddenFor(model => model.Oid)
            @Html.HiddenFor(model => model.ModelBID)
    
            <div class="form-group">
                @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
                </div>
            </div>
    
        </div>
    }
    

    作为HTML的示例(使用时 @Html.EditorFor(model => model.ModelBs)

    B1型:

    <input 
        data-val="true" data-val-required="The Oid field is required." 
        id="ModelBs_f1aa613f-96f4-427f-a568-c70556ad2117__Oid" 
        name="ModelBs[f1aa613f-96f4-427f-a568-c70556ad2117].Oid" 
        type="hidden" 
        value="7e99950b-62c9-e711-afd4-7cb0c2b5b934">
    
    <input 
        id="ModelBs_f1aa613f-96f4-427f-a568-c70556ad2117__ModelAID" 
        name="ModelBs[f1aa613f-96f4-427f-a568-c70556ad2117].ModelAID" 
        type="hidden" 
        value="7e99950b-62c9-e711-afd4-7cb0c2b5b935">
    
    <input 
        class="form-control text-box single-line valid" 
        id="ModelBs_f1aa613f-96f4-427f-a568-c70556ad2117__Name" 
        name="ModelBs[f1aa613f-96f4-427f-a568-c70556ad2117].Name" 
        type="text" 
        value="Model B1" aria-invalid="false">
    

    型号B2:

    <input 
        data-val="true" data-val-required="The Oid field is required." 
        id="ModelBs_128318da-af85-46a5-bc0d-71361610d989__Oid" 
        name="ModelBs[128318da-af85-46a5-bc0d-71361610d989].Oid" 
        type="hidden" 
        value="7e99950b-62c9-e711-afd4-7cb0c2b5b936">
    
    <input 
        id="ModelBs_128318da-af85-46a5-bc0d-71361610d989__ModelAID" 
        name="ModelBs[128318da-af85-46a5-bc0d-71361610d989].ModelAID" 
        type="hidden" 
        value="7e99950b-62c9-e711-afd4-7cb0c2b5b935">
    
    <input 
        class="form-control text-box single-line valid" 
        id="ModelBs_128318da-af85-46a5-bc0d-71361610d989__Name" 
        name="ModelBs[128318da-af85-46a5-bc0d-71361610d989].Name" 
        type="text" 
        value="Model B2" aria-invalid="false">
    

    当使用 for 模型A中的循环,模型B中的循环( @for (var i = 0; i < Model.ModelBs.Count(); i++) { @Html.EditorFor(m => m.ModelBs[i]) } ),索引是数字,但仍然不能返回完整的模型。

    <input 
        data-val="true" data-val-required="The Oid field is required." 
        id="ModelBs_0__Oid" name="ModelBs[0].Oid" 
        type="hidden" 
        value="7e99950b-62c9-e711-afd4-7cb0c2b5b934">
    
    <input 
        id="ModelBs_0__ModelAID" 
        name="ModelBs[0].ModelAID" 
        type="hidden" 
        value="7e99950b-62c9-e711-afd4-7cb0c2b5b935">
    
    <input 
        class="form-control text-box single-line valid" 
        id="ModelBs_0__Name" name="ModelBs[0].Name" 
        type="text" 
        value="Model B1" aria-invalid="false">
    

    型号B2:

    <input 
        data-val="true" data-val-required="The Oid field is required." 
        id="ModelBs_1__Oid" name="ModelBs[1].Oid" 
        type="hidden" 
        value="7e99950b-62c9-e711-afd4-7cb0c2b5b936">
    
    <input 
        id="ModelBs_1__ModelAID" name="ModelBs[1].ModelAID" 
        type="hidden" 
        value="7e99950b-62c9-e711-afd4-7cb0c2b5b935">
    
    <input 
        class="form-control text-box single-line valid" 
        id="ModelBs_1__Name" name="ModelBs[1].Name" 
        type="text" 
        value="Model B 2" aria-invalid="false">
    

    过帐表单数据 :

    @Html.EditorFor(...) 岗位 (未更新ModelCs的ModelBs列表) :

    __RequestVerificationToken:1PfXHdYtb5eE-j6g4DWBEZiRa0trOL8UvYGKVjL0pxR1qOjQE52be7UB14VaIJRpp5UA1Iz9WXt4g_7LKixKhK7ah7Hjp6hOLmLa1m7XavI1
    Oid:7e99950b-62c9-e711-afd4-7cb0c2b5b935
    Name:Model A1
    ModelBs.index:4a481093-9bdd-43ae-b84b-144c576ff346
    ModelBs[4a481093-9bdd-43ae-b84b-144c576ff346].Oid:7e99950b-62c9-e711-afd4-7cb0c2b5b934
    ModelBs[4a481093-9bdd-43ae-b84b-144c576ff346].ModelAID:7e99950b-62c9-e711-afd4-7cb0c2b5b935
    ModelBs[4a481093-9bdd-43ae-b84b-144c576ff346].Name:Model B1
    ModelBs[4a481093-9bdd-43ae-b84b-144c576ff346].ModelCs[0].Oid:7e99950b-62c9-e711-afd4-7cb0c2b5b936
    ModelBs[4a481093-9bdd-43ae-b84b-144c576ff346].ModelCs[0].ModelBID:7e99950b-62c9-e711-afd4-7cb0c2b5b934
    ModelBs[4a481093-9bdd-43ae-b84b-144c576ff346].ModelCs[0].Name:Model C 1
    ModelBs.index:a1dd130d-a1f7-47ed-90a2-28055a960c9b
    

    For 回路柱:

    __RequestVerificationToken:x9hpnm-c1g0Cm9gTnSRjCFIVflziqXqiO3iFkzVpMc33gnNlBoDsvwBHMmRT38sWTCGrFSqCqzcuuBZdXLsXTgX1EbkqUSqPuAtwUrR1XXA1
    Oid:7e99950b-62c9-e711-afd4-7cb0c2b5b935
    Name:Model A1
    ModelBs[0].Oid:7e99950b-62c9-e711-afd4-7cb0c2b5b934
    ModelBs[0].ModelAID:7e99950b-62c9-e711-afd4-7cb0c2b5b935
    ModelBs[0].Name:Model B1
    ModelBs[0].ModelCs[0].Oid:7e99950b-62c9-e711-afd4-7cb0c2b5b936
    ModelBs[0].ModelCs[0].ModelBID:7e99950b-62c9-e711-afd4-7cb0c2b5b934
    ModelBs[0].ModelCs[0].Name:Model C 1
    

    EditorFor 对于 . 某些东西被切断了>(我反复检查了一遍,确认我没有漏掉下面的东西)

    FireFox POST数据,看起来0和1的索引在某种程度上起作用:

    __RequestVerificationToken  qlrlO7Z0_byGZYLGJ6Tbx5Fzmpd0dd6b-JPac4V-f1U-17v06OQr27dYZPh_VmRI3X4nGj7ZAOHtBdERnuZscJlNlgoHAqdeXaNQN04e2qE1
    Oid 7e99950b-62c9-e711-afd4-7cb0c2b5b935
    Name    Model+A1
    ModelBs.index   […]
    0   3d003e30-d350-4fb0-becd-f65207b033c4
    1   be4e35c3-3fee-4c7f-9ee7-580b6e0c8169
    ModelBs[3d003e30-d350-4fb0-becd-f65207b033c4].Oid   7e99950b-62c9-e711-afd4-7cb0c2b5b934
    ModelBs[3d003e30-d350-4fb0-becd-f65207b033c4].ModelAID  7e99950b-62c9-e711-afd4-7cb0c2b5b935
    ModelBs[3d003e30-d350-4fb0-becd-f65207b033c4].Name  Model+B1
    ModelBs[3d003e30-d350-4fb0-becd-f65207b033c4].ModelCs[0].Oid    7e99950b-62c9-e711-afd4-7cb0c2b5b936
    ModelBs[3d003e30-d350-4fb0-becd-f65207b033c4].ModelCs[0].ModelBID   7e99950b-62c9-e711-afd4-7cb0c2b5b934
    ModelBs[3d003e30-d350-4fb0-becd-f65207b033c4].ModelCs[0].Name   Model+C+1
    

    ... 谜团还在继续

    1 回复  |  直到 7 年前
        1
  •  0
  •   Derek    7 年前

    ModelB和ModelC的EditorTemplate文件(cshtml)具有 @using (Html.BeginForm()) { ... } ,删除此选项解决了问题,允许帖子包含所有信息。保留了 BeginForm

    我在查看帖子信息时发现,它显示了一个(n)。第二个模型B的索引,但没有相关数据,它也有一个 form 标签就在下面,每个人都知道许多表单标签并不好。

    更新的cshtml

    模型B。cshtml:

    @model x.Models.Nesting.ModelB
    
    <div class="form-horizontal">
    
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.Oid)
        @Html.HiddenFor(model => model.ModelAID)
    
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>
    
        <div class="form-group">
            @Html.LabelFor(model => model.ModelCs, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
    
                @Html.EditorFor(model => model.ModelCs)
    
                @* Tried the code below as well *@
                @*
                @foreach(var item in Model.ModelCs)
                {
                    @Html.EditorFor(x => item)
                }
                *@
    
            </div>
        </div>
    
    </div>
    

    模型C。cshtml:

    @model x.Models.Nesting.ModelC
    
    <div class="form-horizontal">
    
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.Oid)
        @Html.HiddenFor(model => model.ModelBID)
    
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>
    
    </div>
    
    推荐文章