2016-04-19 2 views
3

In der ASP.Net MVC 5-Anwendung, die ich derzeit schreibe, kann eine Material viele Namen haben (MaterialName s). Ich habe eine Webschnittstelle zum Hinzufügen, Bearbeiten und Löschen dieser Namen für das Material auf den Seiten Edit und Create des Materials erstellt. Um dies zu erreichen, habe ich mehrere text - input s auf den Seiten, die Material.MaterialNames genannt werden. Diese können clientseitig mit Javascript hinzugefügt und gelöscht werden, um die Anzahl der Namen zu ändern. Ich brauche keine Indizes in den name s der input s, weil die Daten, die der Benutzer sehen und bearbeiten sollte, nur eine flache Liste von Strings ist. MVC5 Benutzerdefinierte Bindung: Liste der Zeichenfolgen zu Liste der komplexen Art

Dies sind die relevanten Teile meiner Modelle:

public class MaterialVM 
{ 
    public Material Material { get; set; } 
    // ... 
} 
public class Material 
{ 
    public int Id { get; set; } 
    public List<MaterialName> MaterialNames { get; set; } 
    // ... 
} 
public class MaterialName 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public int MaterialId { get; set; } 
} 

Nun sind alle großen funktionieren würde, wenn Material.MaterialNamesList<string> vom Typ wäre. In meinem Fall kann der Modellbinder MaterialName s nicht aus den mehreren Zeichenkettenwerten erstellen, die als Formulardaten übergeben wurden. Ich glaube, dass der Standard-Ansatz, dies zu beheben wäre

ein Bindemittel benutzerdefiniertes Modells Schreiben

Ist es eine gute Idee, dass wie in this answer zu tun (= BindProperty außer Kraft setzen und nur das Verhalten für eine PropertyType ändern)? Ich würde das mit globally registering the binder für den Typ MaterialVM kombinieren.

Vermisse ich eine einfachere Option?

Ist es nicht möglich, dem Standardbinder einfach eine Methode zum Umwandeln/Konvertieren/Serialisieren/... eines einfachen Typs in einen komplexen Typ anzubieten? Ist meine Vorgehensweise zum Schreiben eines benutzerdefinierten Modellbinders korrekt? Gibt es noch andere Möglichkeiten, die ich noch intuitiver machen könnte?

+0

die Antworten finden Sie [hier] (http://stackoverflow.com/questions/29161481/post-a-form-array-without-successful/29161796#29161796) und [hier] (http://stackoverflow.com/questions/28019793/submit-same-partial -view-called-multiple-mal-data-to-controller/28081308 # 28081308) zum dynamischen Hinzufügen und Löschen komplexer Objekte fr om Sammlungen –

+0

Ich weiß über die Möglichkeit der Verwendung von Indizes. Ich suchte nach einer Lösung ohne sie, weil ich denke, dass sie viel HTML-Overhead produzieren, ohne dass das nötig wäre, da ich nur eine Zeichenkette pro Index habe. –

+0

Da Sie eine Sammlung von komplexen Objekten bearbeiten, müssen Sie Indexer verwenden (es gibt keine Möglichkeit, herauszufinden, welcher 'Name' zu ​​welcher 'Id'- und' MaterialId'-Eigenschaft gehört, besonders wenn Sie Elemente dynamisch hinzufügen und löschen, selbst wenn Sie sollten einen benutzerdefinierten ModelBinder erstellen). Sie können die Indexer nur vermeiden, wenn Ihre Eigenschaft 'öffentliche Liste ist. MaterialNames {get; einstellen; } –

Antwort

1

Die Ansicht Modell der Ansicht sein Catering sollte, so dass es wahrscheinlich ein

List<string> materialNames

Die MVC-Bindung bindet an das View-Modell haben sollte.

Dann in der Steuerung oder was auch immer Schicht verarbeiten Sie die Abbildung Sie die MaterialVM--Material zuordnen.

+0

Ich mag die Idee nicht wirklich, weil ich Daten und Struktur/Objekte duplizieren muss, nur um den Anforderungen des Binders zu entsprechen. Zusätzlich muss ich an allen Stellen, an denen ich bin, zusätzliche Logik hinzufügen Ich möchte den Namen ändern oder ändern lassen, aber vielleicht ist es die beste Option:/ –

+0

Ich stimme dir zu und deshalb bin ich kein großer Fan von MVC (als Framework) oder irgendein Framework, das vorschreibt, wie man ein Anwendung: Ich baue normalerweise Dienste oder verwende Websockets auf der Serverseite und plain html und javascript oder typescript auf der Client-Seite. – DonO

0

Wenn Sie den Cache Ihres MaterialVM in einer Sitzungsvariablen oder Id und MaterialNames in einem Dictionary<int, List<string>>, dann können Sie die Aktion nach zurück, die id und ein List<string> der Namen. Mit der id können Sie das Material nachschlagen und das Modell aktualisieren.

Alternativ können Sie in JS JSON.stringify Ihre Formulardaten, dann analysieren Sie es auf der Serverseite.

0

Sie können einen komplexen Typ mithilfe des Standardmodellbinders binden. Sie müssen jedoch der Vorlage des Wiederholungssteuerelements eine .Index-Eigenschaft hinzufügen.

Hier ist das einfachste Beispiel I für Ihren Fall einfiel:

@model WebApplication25.Models.MaterialVM 

@using (Html.BeginForm()) 
{ 
    @Html.HiddenFor(model => model.Material.Id) 
    <table id="output"> 
     <tr> 
      <th>Name</th> 
      <th>MaterialId</th> 
      <th>Id</th> 
     </tr> 

    </table> 
    <button id="add-more" type="button">Add Another</button> 
    <button type="submit">Submit</button> 
} 
@section scripts{ 
    <script> 
     (function (window) { 
      "use strict"; 
      var index = 0; 
      $("#add-more").on("click", function() { 
       $("#output").append(
        "<tr><td>" + 
        "<input type='hidden' name='Material.MaterialNames.Index' value='" + index + "' />" + // add in the index 
        "<input type='text' name='Material.MaterialNames[" + index + "].Name' /></td>" + 
        "<td><input type='number' name='Material.MaterialNames[" + index + "].MaterialId' /></td>" + 
        "<td><input type='number' name='Material.MaterialNames[" + index + "].Id' />" + 
        "</td></tr>"); 
       index++; 
      }); 

     }(window)); 
    </script> 
} 

Dieses Beispiel in ihnen führen sollte Ihrer Ansicht nach Modell mit: Model bound data list

+1

Ich habe etwas ähnliches zu Ihrer Lösung nur, um asp.net MVC-Modell verbindlich machen mit der Liste der komplexen Objekte arbeiten, da die gebuchten Werte den Indexwert in der Reihenfolge haben müssen. Am Ende habe ich diese versteckten Eingabefelder dynamisch hinzugefügt, bevor das Formular veröffentlicht wurde. – dfdsfdsfsdf

+0

@KMC Die Indizes müssen eigentlich nicht sequenziell sein. Zum Beispiel könnten wir in diesem Code "index + = 2" verwenden, um Werte bewusst zu überspringen - es wird immer noch binden. Sie müssen jedoch alle positive und einzigartige Werte sein. –

+0

Ich erinnere mich an zufällige Indizes wie account.name [0] und account.name [10]. Ich werde es noch einmal versuchen. Vielen Dank. – dfdsfdsfsdf

Verwandte Themen