2

使用 HttpPost 传递对象时出现问题...提交表单后,模型在控制器端设置为“null”,我不知道问题出在哪里。

这是我的控制器:

    public ActionResult AddUser(int id = 0)
    {
        Group group = db.Groups.Find(id);
        List<User> finalList = db.Users.ToList() ;

        return View(new AddUserTemplate()
            {
                group = group,
                users = finalList
            });
//Everything is fine here, the object is greatly submitted to the view
    }



    [HttpPost]
    public ActionResult AddUser(AddUserTemplate addusertemplate)
    {
//Everytime we get in, "addusertemplate" is NULL
        if (ModelState.IsValid)
        {
//the model is null
        }
        return View(addusertemplate);

    }

这是 AddUserTemplate.cs :

    public class AddUserTemplate
{
    public Group group { get; set; }
    public User selectedUser { get; set; }
    public ICollection<User> users { get; set; }
}

这是向控制器返回空值的表单(请注意,下拉列表中大量填充了好的值):

@using (Html.BeginForm()) {
<fieldset>
    <legend>Add an user</legend>
    @Html.HiddenFor(model => model.group)
    @Html.HiddenFor(model => model.users)
    <div class="editor-field">
//Here, we select an user from Model.users list
        @Html.DropDownListFor(model => model.selectedUser, new SelectList(Model.users))
    </div>
    <p>
        <input type="submit" value="Add" />
    </p>
</fieldset>
}

非常感谢你的帮助

4

2 回答 2

2

我试过你的代码,在我的例子中,addusertemplate模型不是空的,但它的属性都是空的。

这是因为一些模型绑定问题:Html.HiddenFor并且Html.DropDownListFor不适用于复杂类型(例如Groupor User)(至少默认情况下是这样)。

此外,Html.HiddenFor无法处理集合。

以下是解决这些问题的方法:

  • 而不是@Html.HiddenFor(model => model.group)应该@Html.HiddenFor为您需要绑定的组的每个属性都有一个

  • 而不是@Html.HiddenFor(model => model.users)您需要遍历用户列表并为每个对象添加@Html.HiddenFor您需要绑定的用户的每个属性

  • 而不是@Html.DropDownListFor(model => model.selectedUser [...],创建一个类似的属性int SelectedUserId {get;set;}并在 DropDownList 中使用它(因为它不能处理复杂类型)。

这是有效的代码:

1.User andGroup类,正如我想象的那样:

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Group
{
    public int Id { get; set; }
    public string Name { get; set; }
}

2.调整AddUserTemplate类:

public class AddUserTemplate
{
    public Group Group { get; set; }
    public IList<User> Users { get; set; }

    public int SelectedUserId { get; set; }

    public User SelectedUser
    {
        get { return Users.Single(u => u.Id == SelectedUserId); }
    }
}

调整:

  • Users已从 更改ICollectionIList,因为我们需要通过索引访问元素(参见视图代码)
  • 添加SelectedUserId的属性,将在 DropDownList 中使用
  • 不是SelectedUser只读属性,它返回当前选择的User.

3.视图的调整代码:

@using (Html.BeginForm())
{
    <fieldset>
        <legend>Add an user</legend>

        @*Hidden elements for the group object*@
        @Html.HiddenFor(model => model.Group.Id)
        @Html.HiddenFor(model => model.Group.Name)

        @*Hidden elements for each user object in the users IList*@
        @for (var i = 0; i < Model.Users.Count; i++)
  {
            @Html.HiddenFor(m => m.Users[i].Id)
            @Html.HiddenFor(m => m.Users[i].Name)
  }
        <div class="editor-field">
            @*Here, we select an user from Model.users list*@
            @Html.DropDownListFor(model => model.SelectedUserId, new SelectList(Model.Users, "Id", "Name"))
        </div>
        <p>
            <input type="submit" value="Add" />
        </p>
    </fieldset>
}
于 2012-11-18T13:26:57.287 回答
0

另一个不需要一堆隐藏字段的选项是简单地指定您希望将模型传递给控制器​​。我认为这更清洁。

@using(Html. BeginForm("action","controller", Model, FormMethod.Post)){
...
}
于 2012-11-18T14:35:06.930 回答