我在寻找其他东西时偶然发现了答案: 实例化后选择列表中的选定值
显然, SelectedValue
属性是只读的,并且只能在瞬时覆盖。当将模型分配给视图(强型)时,SelectListItem的选择值被其构造函数覆盖,其构造函数具有用于页面模型的对象的值。
题
我有一个类别ViewModel,如下:
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; }
}
类别Controller的GET方法使用此类别ViewModel来实例化对象,并将所有产品添加到此类别ViewModel对象中。然后它遍历所有产品,并将所选产品的属性设置为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具有所有具有所选属性的产品仍然设置为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,产品和类别存储在数据库中,并具有多一关系。
解决方案
我在寻找其他东西时偶然发现了答案: 实例化后选择列表中的选定值
显然, SelectedValue
属性是只读的,并且只能在瞬时覆盖。当将模型分配给视图(强型)时,SelectListItem的选择值被其构造函数覆盖,其构造函数具有用于页面模型的对象的值。
其他提示
尝试此代码,我怀疑您的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;
}
因为你 foreach()
代码块正在使用 category.Products
. 。如果您使用 categoryView.Products
, ,您应该看到更改。实际上,您正在选择每个 category.Products
真实,不使用它。我希望现在对您清楚。