我应该使用ViewBag将列表传递给View吗?

时间:2016-03-01 15:01:20

标签: c# asp.net-mvc

不知道为什么我投了票,但在做了一些研究和测试之后我会重新写下我的问题。这是一个侧面项目,我正在学习MVC / EF / Repository / Bootstrap等。我每周只有几个小时在这里工作几个小时。

基本原始问题:

我知道我应该使用List<>在ViewModel中将数据传递给View但我不确定它是否符合我的要求。

我要做的是获取要在表格中显示的用户列表,每个行中都有一个复选框。在该表上方,我希望有一个可以分配给它们的组列表。您从DropDownList(DDL)中选择部分,然后检查要将其分配给谁。这是我想要分配为列表并传递给View的组/部分。

所以,我有一个带有列表的ViewModel,我正在使用一个存储库来填充VM。我不知道该怎么做的确是在哪里/什么时候用每个VM对象填充该列表,即使我这样做又有50个用户,我不想让50次访问数据库以获取相同的信息这就是为什么我认为使用ViewBag将该组列表传递给View的情况可能是合理的。另一方面,我想学习如何在VM中正确填充该列表以供将来编码。

更新了问题/代码:

所以,经过更多研究并遵循一些建议,我现在得到了以下代码。我仍然不确定如何在我的ViewModel中正确填充我的Patrols以便在我的View中填充DDL。

目前我已经在View中显示了带有复选框的表格。现在我又回到了获取值来填充DDL,然后我将不得不在发布到控制器,循环查找检查行和更新数据库。在我的情况下,每个成员记录默认为PatrolId = 0,这个页面应该允许我将PatrolId更新为DDL中的值。

PatrolMemberViewModel中的Patrols属性应该是一个大约5条记录的列表,我将从DB表中提取而不是在DDL中进行硬编码。

视图模型:

 public class PatrolViewModel
    {
        public int PatrolId { get; set; }
        public string PatrolName { get; set; }
    }

    public class PatrolMemberViewModel
    {
        [Key]
        public int MemberId { get; set; }

        public int PatrolId { get; set; }


        [Display(Name = "First Name")]
        public string FirstName { get; set; }


        [Display(Name = "Last Name")]
        public string LastName { get; set; }


        [Display(Name = "Phone")]
        public string PhonePrimary { get; set; }


        [Display(Name = "Email")]
        public string EmailPrimary { get; set; }

        public bool IsSelected { get; set; }

        public PatrolViewModel Patrols { get; set; }

    }

控制器:

public ViewResult Unassigned()
        {
            try
            {
                IEnumerable<PatrolMemberViewModel> model = repository.SelectAllUnassigned();
                return View(model);
            }
            catch (Exception)
            {
                ModelState.AddModelError(string.Empty, "Error retrieving the record.");
                return View();
            }
        }

存储库:

public IEnumerable<PatrolMemberViewModel> SelectAllUnassigned()
        {
            using (DataContext db = new DataContext())
            {
                var results = (from p in db.Person
                               where p.IsActive == true
                               && p.IsScout == true
                               && p.PatrolId == 0
                               select new PatrolMemberViewModel
                               {
                                   MemberId = p.PID,
                                   FirstName = p.FirstName ?? string.Empty,
                                   LastName = p.LastName ?? string.Empty,
                                   EmailPrimary = p.EmailPrimary ?? string.Empty,
                                   PhonePrimary = p.PhonePrimary ?? string.Empty,
                                   PatrolId = p.PatrolId,
                                   IsSelected = false
                               }
                                ).OrderBy(o => o.LastName).ThenBy(o => o.FirstName).ToList();

                return results;
            }
        }

查看:

@model IList<ProjectName.ViewModels.PatrolMemberViewModel>

@{
    ViewBag.Title = "Unassigned";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Patrols</h2>


@using (Html.BeginForm("Update", "Patrol", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(false, "", new { @class = "alert alert-danger" })

    <table class="table table-bordered table-striped table-hover table-condensed tbackground">
        <tr>
            <th class="text-center">

            </th>
            <th class="text-center">
                First Name
            </th>
            <th class="text-center">
                Last Name
            </th>
            <th class="text-center">
                Email
            </th>
            <th class="text-center">
                Phone
            </th>
        </tr>


        @for (var i = 0; i < Model.Count(); i++)
        {
        <tr>
            <td class="text-center">
                @Html.CheckBoxFor(m => m[i].IsSelected)
            </td>
            <td>
                @Html.DisplayFor(m => m[i].FirstName)
            </td>
            <td>
                @Html.DisplayFor(m => m[i].LastName)
            </td>
            <td>
                <a href="mailto:@Model[i].EmailPrimary">@Model[i].EmailPrimary</a>
            </td>
            <td class="text-center">
                @Html.DisplayFor(m => m[i].PhonePrimary)
            </td>
        </tr>
        }

    </table>

    <div class="control-wrapper">
        <input type="submit" id="btnSubmit" value="Assign" class="btn btn-success" />
    </div>
}
<p>&nbsp;</p>

2 个答案:

答案 0 :(得分:1)

首先创建视图模型,以表示您要在视图中显示/编辑的内容。您可以使用PatrolMemberViewModel,但删除[Key]属性以及int PatrolIdPatrolViewModel Patrols属性。

然后创建父视图模型

public class AssignPatrolViewModel
{
    [Display(Name = "Patrol")]
    [Required(ErrorMessage = "Please select a patrol")]
    public int? SelectedPatrol { get; set; }
    public IEnumerable<SelectListItem> PatrolList { get; set; }
    public List<PatrolMemberViewModel> Members { get; set; }
}

你的GET方法将是

public ViewResult Unassigned()
{
  var model = new AssignPatrolViewModel
  {
      PatrolList = new SelectList(db.Patrols, "PatrolId", "PatrolName"), // modify to suit
      Members = repository.SelectAllUnassigned().ToList()
  };
  return View(model);
}

并在视图中

@model AssignPatrolViewModel
....
@using (Html.BeginForm())
{
    @Html.LabelFor(m => m.SelectedPatrol)
    @Html.DropDownListFor(m => m.SelectedPatrol, Model.PatrolList, "Please select")
    @Html.ValidationMessageFor(m => m.SelectedPatrol)
    <table>
        .... // thead elements
        <tbody>
            @for(int i = 0; i < Model.Members.Count; i++)
            {
                <tr>
                    <td>
                        @Html.CheckBoxFor(m => m.Members[i].IsSelected)
                        @Html.HiddenFor(m => m.Members[i].MemberId)
                        // add other hidden inputs for properties you want to post
                    </td>
                    <td>@Html.DisplayFor(m => m.Members[i].FirstName)</td>
                    ....
                </tr>
            }
        </tbody>
    </table>
    <input type="submit" value="Assign" class="btn btn-success" />
}

然后在POST方法中

[HttpPost]
public ViewResult Unassigned(AssignPatrolViewModel model)
{
    if (!ModelState.IsValid)
    {
        model.PatrolList = new SelectList(db.Patrols, "PatrolId", "PatrolName");
        return View(model);
    }
    // Get selected ID's
    IEnumerable<int> selected = model.Members.Where(m => m.IsSelected).Select(m => m.MemberId);
    // Get matching data models
    var members = db.Person.Where(p => selected.Contains(p.PID)); // modify to suit
    // loop each each member, update its PatrolId to the value of model.SelectedPatrol
    // save and redirect
}

答案 1 :(得分:0)

您可以为视图模型创建一个新类,其中包含用户列表和部分列表作为其中的属性。有些人似乎喜欢这种方法。

但我认为使用ViewBag传递部分列表是完全有效的。我一直这样做这样的DDL。