Submit selbe Partial View genannt Mehrfachdaten zum Controller?

Ich habe einen Knopf aus meiner Sicht hinzugefügt. Wenn diese Schaltfläche angeklickt wird, wird eine Teilansicht hinzugefügt. In meiner Form kann ich so viel Teilansicht hinzufügen wie ich kann. Beim Übermitteln dieser Formulardaten kann ich nicht alle Teilansichtsdaten an den Controller senden. Ich habe ein anderes Modell mit allen Attributen gemacht und ich habe eine Liste dieses Modells zu meinem Hauptmodell gemacht. Kann mir bitte irgendwer einen Trick geben, damit ich den gesamten Teil-Inhalt an meinen Controller senden kann?

Meiner Ansicht nach

function addFieldss() { $.ajax({ url: '@Url.Content("~/AdminProduct/GetColorSizeQty")', type: 'GET', success:function(result) { var newDiv = $(document.createElement("div")).attr("id", 'CSQ' + myCounter); newDiv.html(result); newDiv.appendTo("#CSQGroup"); myCounter++; }, error: function(result) { alert("Failure"); } }); }

In meinem Controller

 public ActionResult GetColorSizeQty() { var data = new AdminProductDetailModel(); data.colorList = commonCore.getallTypeofList("color"); data.sizeList = commonCore.getallTypeofList("size"); return PartialView(data); } [HttpPost] public ActionResult AddDetail(AdminProductDetailModel model) { .... } 

In meiner Teilansicht

 @model IKLE.Model.ProductModel.AdminProductDetailModel 
@Html.LabelFor(model => model.fkConfigChoiceCategorySizeId) @Html.DropDownListFor(model => model.fkConfigChoiceCategorySizeId, Model.sizeList, "--Select Size--") @Html.ValidationMessageFor(model => model.fkConfigChoiceCategorySizeId)
@Html.LabelFor(model => model.fkConfigChoiceCategoryColorId) @Html.DropDownListFor(model => model.fkConfigChoiceCategoryColorId, Model.colorList, "--Select Color--") @Html.ValidationMessageFor(model => model.fkConfigChoiceCategoryColorId)
@Html.LabelFor(model => model.productTotalQuantity) @Html.TextBoxFor(model => model.productTotalQuantity) @Html.ValidationMessageFor(model => model.productTotalQuantity)

   

Ihr Problem besteht darin, dass das partielle Rendering von HTML auf einem einzelnen AdminProductDetailModel Objekt basiert, Sie jedoch versuchen, eine Sammlung zurückzuschreiben. Wenn Sie ein neues Objekt dynamisch hinzufügen, fügen Sie weiterhin doppelte Steuerelemente hinzu, die aussehen wie (dies erzeugt aufgrund der doppelten id Attribute auch ungültiges HTML), da sie , usw., um beim Postback an eine Sammlung zu binden.

Der DefaultModelBinder erforderte, dass der Indexer für Auflistungselemente bei null beginnt und fortlaufend ist oder dass die Formularwerte einen Index=someValue wobei der Indexer someValue (z. B. . Dies wird in Phil Haacks Artikel ” Model Binding To A List ausführlich erklärt. Die Verwendung des Index-Ansatzes ist generell besser, weil Sie damit auch Elemente aus der Liste löschen können erforderlich, um alle vorhandenen Steuerelemente umzubenennen, damit der Indexer fortlaufend ist).

Zwei mögliche Ansätze für Ihr Problem.

Option 1

Verwenden Sie den Helper BeginItemCollection für Ihre Teilansicht. Dieser Helper rendert eine versteckte Eingabe für den Index basierend auf einer GUID. Sie benötigen dies sowohl in der Teilansicht als auch in der Schleife, in der Sie vorhandene Elemente rendern. Dein Teil würde ungefähr so ​​aussehen

 @model IKLE.Model.ProductModel.AdminProductDetailModel @using(Html.BeginCollectionItem()) { 
@Html.LabelFor(model => model.fkConfigChoiceCategorySizeId) @Html.DropDownListFor(model => model.fkConfigChoiceCategorySizeId, Model.sizeList, "--Select Size--") @Html.ValidationMessageFor(model => model.fkConfigChoiceCategorySizeId)
.... }

Option 2

Erstellen Sie manuell die HTML-Elemente, die ein neues Objekt mit einem “falschen” Indexer darstellen, platzieren Sie sie in einem ausgeblendeten Container, klonen Sie dann das HTML-Ereignis, aktualisieren Sie die Indexer und den Indexwert und hängen Sie die geklonten Elemente an das DOM an. Um sicherzustellen, dass der HTML-Code korrekt ist, erstellen Sie ein Standardobjekt in einer for Schleife und überprüfen Sie den erzeugten HTML-Code. Ein Beispiel für diesen Ansatz wird in dieser Antwort gezeigt

  

Beachten Sie die Verwendung eines ‘falschen’ Indexers, um zu verhindern, dass dieser für den DefaultModelBinder gebunden wird (‘#’ und ‘%’ passen nicht zusammen, so dass sie vom DefaultModelBinder ignoriert werden)

 $('#addField').click(function() { var index = (new Date()).getTime(); var clone = $('#NewItem').clone(); // Update the indexer and Index value of the clone clone.html($(clone).html().replace(/\[#\]/g, '[' + index + ']')); clone.html($(clone).html().replace(/"%"/g, '"' + index + '"')); $('#yourContainer').append(clone.html()); } 

Der Vorteil von Option 1 besteht darin, dass Sie die Ansicht stark in Ihr Modell eingeben, dies bedeutet jedoch, dass Sie jedes Mal, wenn Sie ein neues Element hinzufügen, einen Aufruf an den Server tätigen. Der Vorteil von Option 2 ist, dass die Clientseite komplett erledigt ist, aber wenn Sie Änderungen an Ihrem Modell vornehmen (z. B. ein validationsattribut zu einer Eigenschaft hinzufügen), müssen Sie den HTML-Code manuell aktualisieren, was die Wartung ein wenig schwieriger macht.

Wenn Sie schließlich die clientseitige validation (jquery-validate-decomputing.js) verwenden, müssen Sie den Validator jedes Mal erneut analysieren, wenn Sie dem DOM neue Elemente hinzufügen, wie in dieser Antwort erläutert.

 $('form').data('validator', null); $.validator.unobtrusive.parse($('form')); 

Und natürlich müssen Sie Ihre POST-Methode ändern, um eine Sammlung zu akzeptieren

 [HttpPost] public ActionResult AddDetail(IEnumerable model) { .... }