2009-10-02 13 views
2

J'ai une configuration de la méthode d'action:modèle de liaison IList d'une sélection d'articles

public ActionResult Delete(IList<Product> products) 

Et une table de produits à mon avis. J'ai Model Binding qui fonctionne de telle sorte que je peux remplir la liste products. Mais je voudrais le remplir avec uniquement les produits sélectionnés via une case à cocher.

Je pense que je pourrais le faire en changeant la méthode d'action à ceci:

public ActionResult Delete(IList<Product> products, IList<int> toDelete) 

Et en passant la liste des cases à cocher au toDelete mais je voudrais vraiment éviter de changer la signature de la méthode si possible.

Existe-t-il un moyen de transmettre uniquement les éléments sélectionnés? Ou vais-je devoir écrire un ModelBinder personnalisé?

Répondre

1

Je ne comprends pas pourquoi vous ne voulez pas changer la signature, mais si vous vraiment ne pas accéder à juste ViewData [ "toDelete"] ou

int[] toDelete; 
UpdateModel(toDelete, "toDelete"); 

ou

public class FormViewModel { 
    IList<Product> Products {get;set;} 
    int[] ToDelete {get;set;} 
} 

var viewmodel = new FormViewModel(); 
UpdateModel(viewmodel, new[]{"Products", "ToDelete"}); 
+0

Ce n'est pas que je * ne peux pas * toucher la signature, c'est que je ne le veux pas vraiment. Si vous lisez une méthode qui dit 'Supprimer (IList produits)' vous savez instantanément qu'il va supprimer les produits dans cette liste. Il est un peu en arrière à lire 'Supprimer (IList produits, int [] toDelete)' ou similaire. Je pourrais avoir un jeu avec votre deuxième suggestion si, acclamations. – jeef3

+0

Après beaucoup de délibérations, j'ai fini par modifier la signature de la méthode pour ajouter un whitelsit. J'ai commencé à faire un classeur de modèle personnalisé mais cela allait prendre trop de temps et j'avais vraiment besoin de continuer. Si j'ai le temps je peux regarder dans le classeur modèle personnalisé à nouveau. – jeef3

2

Vous pouvez toujours utiliser la valeur de la case à cocher pour indiquer si vous souhaitez supprimer l'élément.

Le nom de cette valeur correspond à une propriété de votre classe Product.

<form> 
    <% for(int i = 0; i < products.Count) { %> 
     <div> 
     <input type="hidden" name='<%=string.Format("products[{0}].Property1", i) %>' value='<%= products[i].Property1 %>' /> 
     <input type="hidden" name='<%=string.Format("products[{0}].Property2", i) %>' value='<%= products[i].Property2 %>' /> 
     <input type="hidden" name='<%=string.Format("products[{0}].Property3", i) %>' value='<%= products[i].Property3 %>' /> 
     <input type="checkbox" name='<%=string.Format("products[{0}].ToDelete", i) %>' value='true' /> 
     </div> 
    <% } %> 
</form> 

Alors, quand vous arrivez à votre Delete(), vous pouvez faire quelque chose comme:

products = products.Where(x=>x.ToDelete == false).ToList(); 
+0

Ce serait une bonne façon de le faire, et j'ai essayé de trouver une propriété que je peux attacher un tel drapeau aussi. Malheureusement, je ne peux pas toucher le modèle. – jeef3

+0

Vous pouvez toujours hériter du modèle et utiliser un ViewModel spécial qui ajoute ce champ? Puisqu'ils utilisent la même classe de base, quand vous passez votre sous-classe, votre champ n'affectera rien? – Yablargo