2017-01-06 3 views
1

Ich versuche, unbekannte Menge von Checkboxen zu einer Liste von Booleans zu binden. Nach stundenlanger Suche habe ich keine Lösung gefunden.Asp.net MVC setzen Checkbox Daten in eine Liste von booleans

Dies ist der relevent Teil des Codes aus meiner Sicht:

 @foreach (Device d in Data.GetDevices()) 
    { 
     <label asp-for="NewRegistration.Devices">@d.Name</label> 
     <input asp-for="NewRegistration.Devices" class="checkbox" type="checkbox" /> 
    } 

die Schleife funktioniert, aber wenn ich die Art geändert, wenn der Eingang es gab mir diese Ausnahme Checkbox:

InvalidOperationException: Unerwarteter 'asp-for' Ausdruck Ergebnistyp 'System.Collections.Generic.List`1 [[System.Boolean, System.Private.CoreLib, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = 7cec85d7bea7798e]]'. 'asp-for' muss vom Typ 'System.Boolean' sein, wenn 'type' 'checkbox' ist.

Die Liste ich versuche, meine Daten zu setzen in enthält den folgenden Code:

 private List<bool> _devices; 

    public List<bool> Devices 
    { 
     get { return _devices; } 
     set {_devices = value; } 
    } 

Also meine Frage ist, wie ich Werte aus diesem Kontrollkästchen in der Liste meiner booleans hinzufügen. Wenn ich den Typ der Eingaben nicht festlege, erhalte ich keine Fehler, aber der Typ der Eingabe ist Text. Wenn ich in diesen Eingabefeldern true oder false trage, funktioniert mein Code einwandfrei. Aber ich möchte eine Checkbox, anstatt den Benutzer zu bitten, wahr oder falsch einzugeben.

Vielen Dank für Ihre Zeit!

edit: Meine Frage ist schwer zu erklären. Ich validiere das Formular und verbinde es mit einer Instanz der Registrierungsklasse, die in einem Präsentationsmodell PMRegistration definiert wurde. Ich werde den vollständigen Code unten setzen, wenn die Schnipsel nicht klar genug sind, um

Registrierungsklasse:

public class Registration 
{ 

    public int Id { get; set; } 
    [Required(ErrorMessage = "required field")] 
    [MaxLength(50, ErrorMessage = "To long")] 
    [DisplayName("Name")] 
    public string Name { get; set; } 
    [Required(ErrorMessage = "required field")] 
    [MaxLength(50, ErrorMessage = "To long")] 
    [DisplayName("Firstname")] 
    public string FirstName { get; set; } 
    [Required(ErrorMessage = "required field")] 
    [Range(1,110 ,ErrorMessage = "To long")] 

    public string Age { get; set; } 
    [Required(ErrorMessage = "required field")] 
    [EmailAddress(ErrorMessage ="Not a valid email address")] 
    public string Email { get; set; } 
    [Required(ErrorMessage = "required field")] 
    [DisplayName("slot1")] 
    public int Slot1SessionId { get; set; } 
    [Required(ErrorMessage = "required field")] 
    [DisplayName("slot2")] 
    public int Slot2SessionId { get; set; } 
    [Required(ErrorMessage = "required field")] 
    [DisplayName("slot3")] 
    public int Slot3SessionId { get; set; } 


    private List<bool> _devices; 

    public List<bool> Devices 
    { 
     get { return _devices; } 
     set {_devices = value; } 
    } 

    [Required(ErrorMessage = "required field")] 
    [DisplayName("Organization")] 
    public int OrganizationId { get; set; } 
    public bool ClosingParty { get; set; } 



} 

Meine Ansicht sieht wie folgt aus:

 @using week3.Models; 
 
@model week3.Models.PresentationModels.PMRegistration 
 
<div> 
 
    <h1>New Registration</h1> 
 
    <h2>registration</h2> 
 
</div> 
 
<form class="form-group" asp-controller="Registration" asp-action="New" method="post"> 
 
    <div> 
 
     <label asp-for="NewRegistration.Name">Name:</label> 
 
     <input asp-for="NewRegistration.Name" class="form-control" value="@Model.NewRegistration.Name" /> 
 
     <span asp-validation-for="NewRegistration.Name" class="text-danger"></span> 
 
    </div> 
 
    <div> 
 
     <label asp-for="NewRegistration.FirstName">Firstname:</label> 
 
     <input asp-for="NewRegistration.FirstName" class="form-control" value="@Model.NewRegistration.FirstName" /> 
 
     <span asp-validation-for="NewRegistration.FirstName" class="text-danger"></span> 
 
    </div> 
 
    <div> 
 
     <label asp-for="NewRegistration.Age">Age:</label> 
 
     <input asp-for="NewRegistration.Age" class="form-control" value="@Model.NewRegistration.Age" /> 
 
     <span asp-validation-for="NewRegistration.Age" class="text-danger"></span> 
 
    </div> 
 
    <div> 
 
     <label asp-for="NewRegistration.Email">Email:</label> 
 
     <input asp-for="NewRegistration.Email" class="form-control" value="@Model.NewRegistration.Email" /> 
 
     <span asp-validation-for="NewRegistration.Email" class="text-danger"></span> 
 
    </div> 
 
    <div> 
 
     <div>Pick your sessions</div> 
 
     <label asp-for="NewRegistration.Slot1SessionId" class="form-label">Slot1:</label> 
 
     <select asp-for="NewRegistration.Slot1SessionId" class="form-control" asp-items="@Model.getSessionNamesBySlot(1)" value="@Model.NewRegistration.Slot1SessionId"></select> 
 
     <span asp-validation-for="NewRegistration.Slot1SessionId" class="text-danger"></span> 
 
    </div> 
 
    <div> 
 
     <label asp-for="NewRegistration.Slot2SessionId">Slot2:</label> 
 
     <select asp-for="NewRegistration.Slot2SessionId" class="form-control" asp-items="@Model.getSessionNamesBySlot(2)" value="@Model.NewRegistration.Slot2SessionId"></select> 
 
     <span asp-validation-for="NewRegistration.Slot2SessionId" class="text-danger"></span> 
 
    </div> 
 
    <div> 
 
     <label asp-for="NewRegistration.Slot3SessionId">Slot3:</label> 
 
     <select asp-for="NewRegistration.Slot3SessionId" class="form-control" asp-items="@Model.getSessionNamesBySlot(3)" value="@Model.NewRegistration.Slot3SessionId"></select> 
 
     <span asp-validation-for="NewRegistration.Slot3SessionId" class="text-danger"></span> 
 
    </div> 
 
    
 
     <div>are you wearing dangerous accessoires?</div> 
 

 
     @foreach (Device d in Data.GetDevices()) 
 
     { 
 
      
 
      <label asp-for="NewRegistration.Devices[0]">@d.Name</label> 
 
      <input asp-for="NewRegistration.Devices[0]" class="checkbox" type="checkbox" /> 
 
     } 
 
    <div> 
 
     <label asp-for="NewRegistration.OrganizationId">Organization:</label> 
 
     <select asp-for="NewRegistration.OrganizationId" asp-items="@Model.getOrganizations()" class="form-control"></select><br /> 
 
    <span asp-validation-for="NewRegistration.OrganizationId" class="text-danger"></span> 
 
    </div> 
 
    <div> 
 
     <label asp-for="NewRegistration.ClosingParty">Are you coming to the closing party?</label> 
 
     <input asp-for="NewRegistration.ClosingParty" /> 
 
     <span asp-validation-for="NewRegistration.ClosingParty" class="text-danger"></span> 
 
    </div> 
 
      <input type="submit" class="btn btn-default" value="Register" /> 
 
</form>

+0

Mögliches Duplikat von [MVC 6 Tag Helpers und foreach] (http://stackoverflow.com/questions/31903972/mvc-6-tag-helpers-and-foreach) –

+0

'@foreach (Gerät d in Data.GetDevices()) 'nennst du das Ausführen von Code innerhalb von Razor, anstatt ein Modell mit Daten zu füllen? –

+0

Sollte es nicht so etwas wie asp-for = "@ d.NameOfBooleanProperty" auf der sein? –

Antwort

3

Grund für die Fehler

Ihr Fehler ist, weil Sie dies haben: asp-for="NewRegistration.Devices". Das ist nicht gültig, da das Tag eine Eingabe vom Typ-Ankreuzfeld ist, so erwartet asp-for einen booleschen Wert und Sie senden ihm eine Liste boolescher Werte.

Lösung

Diese Kontrollkästchen für Ihre Geräte erstellen wird:

@foreach (Device d in Data.GetDevices()) 
{ 
    @Html.CheckBox(item); 
} 

Aber meine Vermutung ist, dass Sie der Benutzer diese Checkbox auswählen möchten und sie dann an Sie Post zurück, wenn das das ist Fall, dann müssen Sie dies tun:

Sie benötigen ein Modell wie diese zu erstellen:

public class Device 
{ 
    public string Name { get; set; } 
} 
public class DevicesCollectionModel 
{ 
    public List<Device> AvailableDevices { get; set; } 
    public List<Device> SelectedDevices { get; set; } 
} 

Füllen Sie die DevicesCollectionModel.AvailableDevices und übergeben Sie es zu Ihrer Ansicht. Erstellen Sie in Ihrer Ansicht ein Kontrollkästchen für jedes Gerät in AvailableDevices. Achten Sie auf die name Attribut des Eingangs-Tag unter:

@foreach (var item in Model.AvailableDevices) 
{ 
<div class="checkbox"> 
    <label> 
     <input type="checkbox" 
       name="SelectedDevices" 
       value="@item.Name" /> @item.Name 
     </label> 
    </div> 
} 

Dann in Ihrem Controller, in der Post, müssen Sie die SelectedDevices Eigenschaft zuzugreifen, um herauszufinden, was der Benutzer ausgewählt hat.

Darüber hinaus können Sie separate Modelle erstellen: eines zum Senden an den Benutzer und eines, das der Controller vom Benutzer erhält. Das Modell, das Sie an Ihre Ansicht übergeben, kann nur die AvailableDevices haben und das Modell, das Sie in Ihrem Controller erhalten, kann SelectedDevices haben. MVC bindet es für Sie mit dem Attribut name aus dem Eingabe-Tag.

+0

Ich erkenne die Art und Weise, wie ich mein Problem beschrieben habe, könnte ein wenig verwirrend sein. Die Geräte haben nichts mit der Ausgabe der Liste zu tun. Ich habe den vollständigen Code hinzugefügt, wenn Sie noch interessiert sind. –

+0

Was meinen Sie, die Geräte haben nichts mit der Ausgabe des Codes zu tun? Sie benutzen die Liste, um Checkboxen zu erstellen, also wie hat das nichts damit zu tun? – CodingYoshi

+0

Leider habe ich Ihren Code nicht erhalten! Ich denke, dein Code ist die Lösung, die ich gerade nicht richtig gelesen habe! Vielen Dank! –