无法设置SelectListItem的Selected属性

时间:2013-11-07 15:04:17

标签: c# asp.net-mvc selected selectlistitem

我有一个CategoryViewModel如下:

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

CategoryController的GET方法使用此CategoryViewModel来实例化对象,并将所有Products添加到此CategoryViewModel对象。然后,它遍历所有产品并将产品的Selected属性设置为True,它们包含在类别对象中:

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

使用调试器,我观察到foreach执行,但categoryView将所有具有Selected属性的Products仍设置为False。

然而,这个工作正常:

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

有人可以解释一下这个差异以及为什么第一个不起作用?

修改 我使用的是EF 6,产品和类别存储在具有多对多关系的数据库中。

3 个答案:

答案 0 :(得分:2)

我在搜索其他内容时偶然找到了答案:Set selected value in SelectList after instantiation

显然,SelectedValue属性是只读的,只能在实例期间覆盖。将模型分配给视图(强类型)时,SelectListItem的SelectedValue将被其构造函数覆盖,其中包含用于页面模型的对象的值。

答案 1 :(得分:1)

试试这段代码,我怀疑你的foreach循环可能会抛出异常,所以你可以检查返回值是否为null。

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

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

答案 2 :(得分:0)

因为您的foreach()代码块正在使用category.Products。如果您使用categoryView.Products,您应该会看到更改。您实际上将每个category.Products的选定项设置为true,之后不再使用它。我希望你现在很清楚。