【问题标题】:Can not set Selected property of SelectListItem无法设置 SelectListItem 的 Selected 属性
【发布时间】:2014-01-17 18:01:15
【问题描述】:

我有一个 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 实例化一个对象并将所有产品添加到此 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 属性的产品仍设置为 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,产品和类别以多对多关系存储在数据库中。

【问题讨论】:

  • 可能在您的 foreach 循环中,该行会引发异常。因为引用类型默认值为 null,并且 null 没有 Selected 属性。您确定它不会引发异常吗?
  • @Selman22 是的,它处于调试模式,如果尝试设置空引用的属性,则会引发错误。但会再次测试以确保。
  • 那么我的假设是正确的 =) 检查我的答案,然后再试一次
  • @Selman22 抱歉我的回答含糊。我想说的是“是的,它在空引用的情况下抛出异常,但在这种情况下我没有收到异常。”。

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    试试这段代码,我怀疑你的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;
     }
    

    【讨论】:

    • categoryView.Products 包含ProductRepo.GetAllProducts() 获得的所有我的产品,category.Products 是这些产品的子集。所以Where 语句总是返回一个非空对象(在调试中测试过)。我会再次测试它并确定让您知道。
    【解决方案3】:

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

    【讨论】:

    • 很抱歉没有测试就问了(不幸的是我不在我的电脑旁),但我看不到你的意思。 foreach() 块遍历 category.Products,它们是分配给特定类别的产品。这样做,我在所有查看的产品中将对应的SelectListItemSelected 布尔变量设置为true。我不明白如何设置分配给某个类别的产品的“已选择”。因为Product 类没有这样的属性。那么编译器不应该抱怨吗?另请参阅我对问题的编辑。谢谢!
    • 我担心的是代码categoryView.Products.Where(x =&gt; x.Value == product.Id).FirstOrDefault().Selected = true; 可能没有返回任何FirstOrDefault(),因为x.Value 可能不等于product.Id。抱歉,如果这可能是错误的,我只是在我的大脑中运行代码。试试这个,看看这是否有效categoryView.Products.Where(x =&gt; x == product).FirstOrDefault().Selected = true;
    • 很遗憾,您的建议无法尝试,因为 lambda 函数中的xSelectListItem,而productProduct 类的对象。因此,它不会编译。我其实找到了原因,现在分享一下。
    猜你喜欢
    • 2012-02-12
    • 2016-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多