2017-11-15 2 views
0

Modell auf Speichern Die Bindung ist nicht vollständige Liste der verschachtelten Objekten zurückkehren, maximal einModell auf Speichern Bindung kehrt nicht vollständige Liste der verschachtelten Objekten, maximal ein

Versuch EditorTemplates zu verstehen, hier ist eine einfache Beispiel, das momentan nicht funktioniert. Das Modell gibt nicht die vollständige IList der Elemente zurück, es scheint jedes Mal ein Objekt zurückzugeben, wenn es in meinem Beispiel 2 geben sollte.

Wenn ich bearbeiten ModelA, das Beispiel ist:

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

Diese Liste zeigt ordnungsgemäß während bearbeiten, aber auf Speichern, einige der Informationen ist „verloren“, (not found) unten hinzugefügt.

- 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) 

Beim Speichern gibt das Modell grundsätzlich nicht mehr als ein Objekt aus einer Liste zurück.

Klassen:

Baseobject:

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

} 

ModelA, Modell B und ModelC:

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

Grund Controller für ModelA, hier ist der Edit:

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

Aufrufe:

Edit.cshtml (für ModelA):

@model x.Models.Nesting.ModelA 

@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken() 
    @Html.EditorForModel(Model) 
} 

Aufrufe in Aufrufe/Shared/EditorTemplates:

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> 

ModelB.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> 
} 

ModelC.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> 
} 

Als Beispiel aus dem HTML (wenn @Html.EditorFor(model => model.ModelBs) verwendet wird), gibt die Bindung für beide Objekte Modell B aussehen schauen, wie sie richtig gebunden wäre (aber nur das erste Objekt):

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

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

Bei der Verwendung der for-Schleife in ModelA, SchleifenmodellB (@for (var i = 0; i < Model.ModelBs.Count(); i++) { @Html.EditorFor(m => m.ModelBs[i]) }), sind die Indizes Zahlen, geben aber immer noch keine vollständigen Modelle zurück.

Modell B1:

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

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

POST Formulardaten:

@Html.EditorFor(...) POST (nicht ModelBs Liste der ModelCs aktualisieren):

__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 loop POST:

__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 hat ModelBs.index zweimal (hoffnungsvoll dies führt zu einer Lösung), aber nicht in den For. Etwas abgeschnitten zu werden> (I doppelt und dreifach überprüft, dass ich nicht etwas fehlte weiter unten)

FireFox POST-Daten, sieht aus wie die Indizes 0 und 1 arbeiten zu einem gewissen Grad:

__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 

... das Mysterium geht weiter

+0

Wie sehen Sie Ihre Eingabe-Tags, wie wenn man die für Schleifen mit den Indizes verwenden

cshtml

ModelB.cshtml aktualisiert? Die typische Modellbinder funktioniert, wenn Sie Eingaben mit Namen wie 'ModelBs [0] .Name' und' ModelBs [1] .Name' haben. Die zufälligen Guids darin brechen es. Ich bin mir nur nicht sicher, woher diese kommen. – Becuzz

+0

Meine Frage wurde aktualisiert, um die 'for' Loop-Ergebnisse anzuzeigen. – Derek

+0

Das würde ich erwarten zu arbeiten. Und das bringt dir immer nur ein Ergebnis pro Liste? – Becuzz

Antwort

0

Die EditorTemplate-Dateien (cshtml) für ModelB und ModelC hatten @using (Html.BeginForm()) { ... }, das Entfernen löste das Problem und erlaubte dem POST, alle Informationen zu enthalten. Halten Sie die BeginForm auf ModelA, die erforderlich ist.

Ich fand es bei der Überprüfung der POST-Informationen, es zeigte eine (n) .index für das zweite ModelB, aber keine damit verbundenen Daten, es hat auch einen form Tag direkt unter, jeder weiß, dass viele Form-Tags nicht ist gut.

@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> 

ModelC.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> 
+0

Meine Frage jetzt, wenn ich die 'FormData' zurück in (um es falsch zu machen) hinzufügen, warum hat Modell B1 kein' form' Tag (gut), aber Modell B2 (schlecht) Sie verwenden beide dieselbe EditorTemplate-Datei. Was ist die Logik hinter Razor dafür? – Derek

Verwandte Themen