Passar lista de checkboxs de seleção na visualização e retirada IEnumerable

Eu tenho uma lista de itens que serão associados a um usuário. É um relacionamento um-para-muitos. Eu quero toda a lista de itens passados ​​para a visão para que eles possam escolher aqueles que ainda não estão associados a eles (e também ver aqueles que já estão associados). Eu quero criar checkboxs de seleção destes. Eu então quero enviar os selecionados de volta para o controlador a ser associado. Como posso passar na lista de todos eles, incluindo aqueles que ainda não estão associados, e transferi-los de volta para serem associados?

Aqui está o que eu tentei primeiro, mas está claro que isso não funcionará, pois estou baseando as inputs nos itens transmitidos através da coleção AllItems , que não tem nenhuma conexão com os Itens no próprio usuário.

 
@foreach (var item in Model.AllItems) {
}

Você não pode ligar a uma coleção usando um loop foreach . Você também não deve gerar manualmente o seu html, o que, neste caso, não funcionaria, porque as checkboxs de seleção desmarcadas não são postadas de volta. Sempre use os helpers html fortemente tipados para obter a vinculação correta do modelo bidirecional.

Você não indicou quais são seus modelos, mas supondo que tenha um User e deseja selecionar Roles para esse usuário, crie modelos de exibição para representar o que deseja exibir na exibição

 public class RoleVM { public int ID { get; set; } public string Name { get; set; } public bool IsSelected { get; set; } } public class UserVM { public UserVM() { Roles = new List(); } public int ID { get; set; } public string Name { get; set; } public List Roles { get; set; } } 

No método GET

 public ActionResult Edit(int ID) { UserVM model = new UserVM(); // Get you User based on the ID and map properties to the view model // including populating the Roles and setting their IsSelect property // based on existing roles return View(model); } 

Visão

 @model UserVM @using(Html.BeginForm()) { @Html.HiddenFor(m => m.ID) @Html.DisplayFor(m => m.Name) for(int i = 0; i < Model.Roles.Count; i++) { @Html.HiddenFor(m => m.Roles[i].ID) @Html.CheckBoxFor(m => m.Roles[i].IsSelected) @Html.LabelFor(m => m.Roles[i].IsSelected, Model.Roles[i].Name) }  } 

Então, no método post, seu modelo será vinculado e você poderá verificar quais papéis foram selecionados

 [HttpPost] public ActionResult Edit(UserVM model) { // Loop through model.Roles and check the IsSelected property } 

Não parece que você estará excluindo as checkboxs de seleção dinamicamente, o que torna esse problema muito mais fácil de resolver. Observação: A solução a seguir não funcionará como esperado se você permitir que clientes ou scripts removam dinamicamente as checkboxs de seleção da página, pois os índices não serão mais sequenciais.

A vinculação do modelo MVC não é infalível, portanto, às vezes, é preciso ajudá-lo. O fichário do modelo sabe que precisa se ligar a uma propriedade chamada Itens porque o nome do campo de input é Itens, mas não sabe que Itens é uma lista. Portanto, supondo que em seu controlador você tenha uma lista de itens para modelar bind to called Items, o que você precisa fazer é ajudar o MVC a reconhecer que você está vinculando a uma lista. Para isso, especifique o nome da lista e um índice.

 
@for (var i = 0; i < Model.AllItems.Count; i++) {
}

A linha chave aqui é esta:

Observe os itens [@i]? Isso está dizendo ao fichário do modelo para procurar uma propriedade chamada Items e vincular esse valor ao índice em i for Items.