【问题标题】:Setting selected property in SelectList for each object in collection based on selected ID in ASP.NET MVC 3根据 ASP.NET MVC 3 中的选定 ID 在 SelectList 中为集合中的每个对象设置选定属性
【发布时间】:2012-12-05 19:01:45
【问题描述】:

跟进问题: Populate a list property from delimited string

我遇到的问题是我的编辑视图中的下拉框没有根据 BugAssignment 模型中的 AssignedUserID 属性保留/选择正确的项目。

型号:

public class BugAssignment
{
    public int BugAssignmentID { get; set; }
    public int BugNumber { get; set; }
    public int? AssignedUserID { get; set; }
    public virtual User AssignedUser { get; set; }
    public virtual Status Status { get; set; }
    public IEnumerable<SelectListItem> Users { get; set; }
}

public class BugAssignmentList
{
    public BugAssignmentList()
    {
        BugAssignments = new List<BugAssignment>();
    }
    public int BugAssignmentListID { get; set; }
    public string Name { get; set; }
    public List<BugAssignment> BugAssignments { get; set; }
}

编辑/详细视图模型

public class BugAssignmentListDetailsViewModel
{
    public int BugAssignmentListID { get; set; }
    public string Name { get; set;}
    public List<BugAssignment> BugAssignments { get; set; }
}

我的控制器中有以下两种方法:

    public ActionResult Edit(int id)
    {
        var balData = db.BugAssignmentLists.Include(bn => bn.BugAssignments).ToList();
        //this is a reference to the bug assignment list object whose ID was passed in
        BugAssignmentList bugAssignmentList = balData.Where(b => b.BugAssignmentListID == id).FirstOrDefault();
        //loop through the bug assignment list and for each bug assignment
        foreach (BugAssignment b in bugAssignmentList.BugAssignments)
        {
            //create the select list for each BugAssignment object
            b.Users = users.Select(u => new SelectListItem
            {
                Value = u.UserID.ToString(),
                Text = u.FullName,
                Selected = u.UserID == b.AssignedUserID //<<THIS IS WHERE IT IS MESSING UP
            });

        }
        BugAssignmentListDetailsViewModel detailsVM = new BugAssignmentListDetailsViewModel
        {
            BugAssignmentListID = id
        };
        if (bugAssignmentList != null)
        {
            detailsVM.BugAssignments = bugAssignmentList.BugAssignments;
            detailsVM.Name = bugAssignmentList.Name;
        }
        return View(detailsVM);
    }

    // POST
    [HttpPost]
    public ActionResult Edit(BugAssignmentListDetailsViewModel viewModel)
    {
        var balData = db.BugAssignmentLists.Include(bn => bn.BugAssignments).ToList();
        var users = db.Users.ToList();
        BugAssignmentList bugAssignmentList = balData.Where(b => b.BugAssignmentListID == viewModel.BugAssignmentListID).FirstOrDefault();
        bugAssignmentList.Name = viewModel.Name;
        bugAssignmentList.BugAssignments = viewModel.BugAssignments;

        if (ModelState.IsValid)
        {
            UpdateModel(bugAssignmentList, "BugAssignmentList");
            db.Entry(bugAssignmentList).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(bugAssignmentList);
    }

查看:

<table>    
<thead>
    <th>
        Bug Number
    </th>
    <th>
        Assigned User
    </th>
</thead>
    @for(int i=0; i<Model.BugAssignments.Count(); i++)
    {
        <tr>
            <td style="text-align: center;">
                @Html.EditorFor(modelItem => Model.BugAssignments[i].BugNumber)
            </td>
            <td>
                @Html.DropDownListFor(modelItem => Model.BugAssignments[i].AssignedUserID, Model.BugAssignments[i].Users, "-- Select User --")
                @Html.HiddenFor(modelItem => Model.BugAssignments[i].BugAssignmentID)
            </td>
        </tr>
    }
</table>

POST 工作正常。查看数据库,BugAssignmentList 中的 BugAssignments 集合中的每个 BugAssignment 都使用我的 Edit 视图的下拉框中的正确 AssignedUserID 进行更新,因此它不是 POST 方法。

问题出在 Edit(int id) 中。发生的事情很奇怪。我在 foreach 循环之前放置了一个断点,并查看了 bugList.BugAssignments 的内部。所有 AssignedUserID 都是正确的,但在循环完成后,我再次检查列表,BugAssignment.Users 中的所有 SelectListItems 都选择了相同的用户。

以下代码有什么问题会导致这种情况?

    foreach (BugAssignment b in bugAssignmentList.BugAssignments)
    {
        //create the select list for each BugAssignment object
        b.Users = users.Select(u => new SelectListItem
        {
            Value = u.UserID.ToString(),
            Text = u.FullName,
            Selected = u.UserID == b.AssignedUserID //<<THIS IS WHERE IT IS MESSING UP
        });

    }

另外,作为旁注:我希望界面看起来像这样(这就是为什么我需要 SelectList 在 BugAssignment 模型上,除非有更简单的方法。我不想写 BugAssignment控制器/视图我希望有人能够快速为用户分配错误编号,如下所示:

这是另一个屏幕截图,可以更好地显示正在发生的事情:

【问题讨论】:

    标签: asp.net-mvc-3 entity-framework drop-down-menu selectlistitem


    【解决方案1】:

    我认为这是一个关闭问题。尝试创建b.assignedUserID 的本地副本:

    foreach (BugAssignment b in bugAssignmentList.BugAssignments)
    {
        var assignedUserID = b.AssignedUserID;
    
        //create the select list for each BugAssignment object
        b.Users = users.Select(u => new SelectListItem
        {
            Value = u.UserID.ToString(),
            Text = u.FullName,
            Selected = (u.UserID == assignedUserID),
        });
    
    }
    

    【讨论】:

    • 我读了一些关于闭包问题的书...我对 C# 和 ASP.NET 还是很陌生,我想这是你必须意识到的陷阱之一.再次感谢。
    【解决方案2】:

    我猜这是闭包的问题。由于您在 lambda 中生成 SelectListItem,因此它只获取第一个 b.AssignedUserID 的副本并在任何地方使用它。这方面的一些阅读材料: Is there a reason for C#'s reuse of the variable in a foreach?

    我认为这个修改可能会解决问题:

    foreach (BugAssignment b in bugAssignmentList.BugAssignments)
        {
            var bugAssignedUser = b.AssignedUserID;
            //create the select list for each BugAssignment object
            b.Users = users.Select(u => new SelectListItem
            {
                Value = u.UserID.ToString(),
                Text = u.FullName,
                Selected = u.UserID == bugAssignedUser  //<<THIS IS WHERE IT IS MESSING UP
            });
    
        }
    

    【讨论】:

    • 感谢您提供的链接,我正要向上面的发帖人询问有关为什么这不起作用的更多信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    • 2010-11-24
    相关资源
    最近更新 更多