Comment passer la liste IEnumerable au contrôleur dans MVC y compris l'état de la case à 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 de 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 Soumettre:

 public ActionResult BlockedIPList(IEnumerable<BlockedIPViewModel> lstBlockedIPs)
 {

  }

mais j'obtiens la valeur null à lstBlockedIPs en venant à l'action du controller.J'ai besoin de l'état de la case à cocher ici. S'il vous plaît aider.

46
demandé sur abatishchev 2013-06-11 10:35:30

1 réponses

utilisez une liste à la place et remplacez votre foreach boucle for boucle:

@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 aussi utiliser un modèle d'éditeur:

@model IEnumerable<BlockedIPViewModel>

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

et ensuite définir le modèle ~/Views/Shared/EditorTemplates/BlockedIPViewModel.cshtml qui sera automatiquement affiché 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 null dans votre controller est parce que vous n'avez pas respecté la convention de nommage pour vos champs d'entrée que le binder model par défaut s'attend à ce que se connecter 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 précisément les noms des champs d'entrée) avec mon exemple et le vôtre. Ensuite comparer et vous comprendrez pourquoi le vôtre ne fonctionne pas.

90
répondu Darin Dimitrov 2013-06-11 06:39:35