web-dev-qa-db-fra.com

Comment passer la liste IEnumerable au contrôleur dans MVC, y compris l'état des cases à cocher?

J'ai une application MVC dans laquelle j'utilise un modèle comme celui-ci:

 public class BlockedIPViewModel
{
    public string  IP { get; set; }
    public int ID { get; set; }
    public bool Checked { get; set; }
}

Maintenant, j'ai une vue pour lier une liste comme ceci:

@model IEnumerable<OnlineLotto.Web.Models.BlockedIPViewModel>
@using (Html.BeginForm())
{
  @Html.AntiForgeryToken()
}

@foreach (var item in Model) {
<tr>
    <td>

        @Html.HiddenFor(x => item.IP)           
        @Html.CheckBoxFor(x => item.Checked)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.IP)
    </td>

</tr>
}

<div>
    <input type="submit" value="Unblock IPs" />
</div>

Maintenant, j'ai un contrôleur pour recevoir l'action du bouton d'envoi:

 public ActionResult BlockedIPList(IEnumerable<BlockedIPViewModel> lstBlockedIPs)
 {

  }

Mais j'obtiens une valeur nulle pour lstBlockedIPs lorsque je viens à l'action du contrôleur. J'ai besoin d'obtenir l'état de la case à cocher ici. S'il vous plaît aider.

47
Praveen VR

Utilisez plutôt une liste et remplacez votre boucle foreach par une boucle for:

@model IList<BlockedIPViewModel>

@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken()

    @for (var i = 0; i < Model.Count; i++) 
    {
        <tr>
            <td>
                @Html.HiddenFor(x => x[i].IP)           
                @Html.CheckBoxFor(x => x[i].Checked)
            </td>
            <td>
                @Html.DisplayFor(x => x[i].IP)
            </td>
        </tr>
    }
    <div>
        <input type="submit" value="Unblock IPs" />
    </div>
}

Vous pouvez également utiliser un modèle d’éditeur:

@model IEnumerable<BlockedIPViewModel>

@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken()
    @Html.EditorForModel()   
    <div>
        <input type="submit" value="Unblock IPs" />
    </div>
}

puis définissez le modèle ~/Views/Shared/EditorTemplates/BlockedIPViewModel.cshtml qui sera automatiquement rendu pour chaque élément de la collection:

@model BlockedIPViewModel
<tr>
    <td>
        @Html.HiddenFor(x => x.IP)
        @Html.CheckBoxFor(x => x.Checked)
    </td>
    <td>
        @Html.DisplayFor(x => x.IP)
    </td>
</tr>

La raison pour laquelle vous obteniez une valeur nulle dans votre contrôleur est que vous n'avez pas respecté la convention de dénomination de vos champs d'entrée que le classeur de modèle par défaut s'attend à lier avec succès à une liste. Je vous invite à lire le following article .

Une fois que vous l'avez lu, regardez le HTML généré (et plus spécifiquement les noms des champs de saisie) avec mon exemple et le vôtre. Ensuite, comparez et vous comprendrez pourquoi le vôtre ne fonctionne pas.

91
Darin Dimitrov