【问题标题】:@Html.DropDownListFor and viewmodel not posting back to controller?@Html.DropDownListFor 和 viewmodel 没有发回控制器?
【发布时间】:2016-01-27 10:04:31
【问题描述】:

是时候上网问问了。我是一名学生,总体上对 MVC + 编码非常陌生,但我一生都无法弄清楚为什么这不起作用。可能是非常明显的事情。 :/

我有一个视图 (AddMemberToGroup),它被强类型化为视图模型 (PersonGroupingViewModel)。我想要做的是将一个人添加到一个组中,用户从视图的下拉列表中选择一个组。

视图模型:

public class PersonGroupingViewModel
{
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set;}

    public List<Group> Memberships { get; set; }

    public SelectList AllGroups { get; set; }
    public int SelectedGroupId { get; set; }

}

控制器:

//GET People/AddToGroup
public ActionResult AddMemberToGroup(int? PersonId)
{
    if (PersonId == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
    }

    Person person = db.People.Find(PersonId);
    if (person == null)
    {
        return HttpNotFound();
    }

    SelectList allthegroups = new SelectList(db.Groups, "GroupId", "Name");

    PersonGroupingViewModel viewmodel = new PersonGroupingViewModel();
    viewmodel.PersonId = person.PersonId;
    viewmodel.FirstName = person.FirstName;
    viewmodel.LastName = person.LastName;
    viewmodel.AllGroups = allthegroups;

    //viewmodel.Memberships cannot be empty
    if (person.Memberships == null)
    {
        viewmodel.Memberships = new List<Group>();
    }
    else 
    { 
        viewmodel.Memberships = person.Memberships.ToList(); 
    }

    return View(viewmodel);
}

//POST: People/AddToGroup 
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddMemberToGroup(PersonGroupingViewModel vm)
{
    SelectList allthegroups = new SelectList(db.Groups, "GroupId", "Name");
    vm.AllGroups = allthegroups; 

    int PersonId = vm.PersonId;
    int GroupId = vm.SelectedGroupId;

    Person person = db.People.Find(PersonId);
    Group group = db.Groups.Find(GroupId);
    group.Members.Add(person);
    db.SaveChanges();

    return View(vm);
}

查看表单(强类型为 PersonGroupingViewModel):

将成员添加到组


@using (Html.BeginForm())
{
@Html.AntiForgeryToken()

<div>
    <h4>Groups @Html.DisplayFor(model => model.FirstName) is already in:</h4>
    <ul>
        @foreach (var group in Model.Memberships)
        {
            <li>@Html.DisplayFor(modelItem => group.Name)</li>
        }
    </ul>
</div>

<div class="form-horizontal">
    <h4>Add @Html.DisplayFor(model => model.FirstName) @Html.DisplayFor(model => model.LastName) To Group:</h4>

    @Html.HiddenFor(model => model.PersonId)

    <div class="form-group">
        <label>Group: </label>
        @Html.DropDownListFor(m => m.SelectedGroupId, Model.AllGroups, String.Empty)
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Add To Group" class="btn btn-default" />
        </div>
    </div>
</div>
}

当我在浏览器中单击“提交”时,我会返回一个 URL: localhost:54696/People/AddMemberToGroup?PersonId=1

除了控制器中Group group = db.Groups.Find(GroupId); 行上的异常“对象引用未设置为对象的实例”。

返回的视图模型是空的还是根本没有?我不确定发生了什么,并希望有人尝试用小词解释它。我已经做了很多谷歌搜索并尝试了一些建议,但最后我觉得我好像在绕圈子。

【问题讨论】:

  • 就 url 而言,将方法更改为 AddMemberToGroup(int? ID) 假设您使用默认路由或添加特定路由 url: yourController/AddMemberToGroup/{PersonId}
  • 您还为选择生成了一个null 标签选项,而不是检查ModelState,因此如果没有选择任何组,您可能会抛出异常。您需要调试代码并检查所有值是否正确设置,而不是null。但是我建议这是一个糟糕的用户界面。您一次只能选择一个组,您还可以选择已经选择的组(也可能引发异常)并且在返回视图之前不重新分配 vm.Memberships 的值,因此 @foreach (var group in Model.Memberships) 也会抛出一个例外。
  • 更好的方法是生成所有组的选中列表框,以便您可以根据需要选择和取消选择组 - 请参阅 this answer 示例
  • @StephenMuecke 感谢 cmets,我弄清楚了为什么它不起作用并发布了我的答案。我正在考虑稍后更改为复选框,但该应用程序的重点是组织真正的小团体(可能一次管理 20 人),每个成员只有 也许 2 或 3 个子组,并且通常只有一个。不过,我确实需要阻止它向他们已经在的组中添加成员!

标签: c# asp.net-mvc dropdown


【解决方案1】:

解决了...

group.Members 为空,因此 group.Members.Add(person) 不起作用。如果列表为空,则在 if/else 语句中实例化一个新成员列表,并且它工作正常:

if (group.Members == null)
            {
                group.Members = new List<Person>();
                group.Members.Add(person);
            }
            else {
                group.Members.Add(person);
            }

【讨论】:

    猜你喜欢
    • 2015-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    相关资源
    最近更新 更多