我有一个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,产品和类别存储在具有多对多关系的数据库中。
答案 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,之后不再使用它。我希望你现在很清楚。