Question

J'ai une catégorieViewModel comme suit:

public class CategoryViewModel
{
    public string Id {get; set;}
    public string Name { get; set; }
    public IEnumerable<SelectListItem> Products { get; set; }
    public List<string> SelectedProductIds { get; set; }
}

La méthode GET de CatégoryController utilise cette catégorie ViewModel pour instancier un objet et ajoute tous les produits à cet objet CatégoryViewModel. Ensuite, il itère à travers tous les produits et définit la propriété sélectionnée des produits à TRUE qui sont incluses dans l'objet de catégorie:

public ActionResult CategoryController(string categoryId)
{
    CategoryDbContext db = new CategoryDbContext();
    CategoryRepository CategoryRepo = new CategoryRepository(db);
    ProductRepository ProductRepo = new ProductRepository(db);

    Category category = CategoryRepo.GetCategory(categoryId);

    CategoryViewModel categoryView = new CategoryViewModel() 
    {
        Id = category.Id,                   
        Name = category.Name,                             
        Products = from product in ProductRepo.GetAllProducts()
                   select new SelectListItem { Text = product.Name, Value = product.Id, Selected = false}
    };

        foreach (var product in category.Products)
        {
           categoryView.Products.Where(x => x.Value == product.Id).FirstOrDefault().Selected = true;
        }

    return View(categoryView);
}

En utilisant le débogueur, j'observe que ForEach s'exécute, mais CatégoryView a tous les produits avec une propriété sélectionnée toujours définie sur False.

Cependant, celui-ci fonctionne bien:

public ActionResult CategoryController(string categoryId)
{
    CategoryDbContext db = new CategoryDbContext();
    CategoryRepository CategoryRepo = new CategoryRepository(db);
    ProductRepository ProductRepo = new ProductRepository(db);

    Category category = CategoryRepo.GetCategory(categoryId);

    CategoryViewModel categoryView = new CategoryViewModel() 
    {
        Id = category.Id,                   
        Name = category.Name,                             
        Products = from product in ProductRepo.GetAllProducts()
                   select new SelectListItem { Text = product.Name, Value = product.Id, Selected = category.Products.Contains(product)}
    };

    return View(categoryView);
}

Quelqu'un peut-il expliquer la différence et pourquoi le premier ne fonctionne pas?

ÉDITER:J'utilise EF 6 et les produits et les catégories sont stockés dans la base de données avec une relation plusieurs à plusieurs.

Était-ce utile?

La solution

J'ai trouvé la réponse par hasard en cherchant autre chose: Définir la valeur sélectionnée dans SelectList après l'instanciation

Apparemment, le SelectedValue La propriété est en lecture seule et ne peut être écrasée que pendant l'instantion. Lorsqu'un modèle est affecté à la vue (fortement typé), la valeur sélectionnée du selectListItem est écrasée par son constructeur avec la valeur de l'objet utilisé pour le modèle de page.

Autres conseils

Essayez ce code, je soupçonne que votre boucle foreach peut lancer une exception, afin que vous puissiez vérifier si la valeur de retour est nul.

foreach (var product in category.Products)
{
    var p = categoryView.Products.Where(x => x.Value == product.Id).FirstOrDefault();

    if(p != null) p.Selected = true;
 }

Parce que votre foreach() Le bloc de code utilise category.Products. Si tu utilises categoryView.Products, vous devriez voir le changement. Vous définissez pratiquement sélectionné de chacun category.Products à vrai et ne pas l'utiliser après. J'espère que c'est clair pour vous maintenant.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top