Can not set Selected property of SelectListItem

Ferit Buyukkececi picture Ferit Buyukkececi · Nov 7, 2013 · Viewed 8.1k times · Source

I have a CategoryViewModel as follows:

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; }
}

The GET method of CategoryController uses this CategoryViewModel to instantiate an object and adds all Products to this CategoryViewModel object. Then it iterates through all the products and sets the Selected property of products to True which are included in the category object:

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);
}

Using the debugger, I observe that foreach executes, but categoryView has all Products with Selected property still set to False.

However, this one works fine:

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);
}

Can someone please explain the difference and why the first one doesn't work?

EDIT: I am using EF 6 and Products and Categories are stored in the database with many-to-many relationship.

Answer

Ferit Buyukkececi picture Ferit Buyukkececi · Jan 10, 2014

I found the answer by chance while searching for something else: Set selected value in SelectList after instantiation

Apparently, the SelectedValue property is read-only and can only be overwritten during instantion. When a model is assigned to the view (strongly-typed), the SelectedValue of the SelectListItem is overwritten by its constructor with the value of the object used for page model.