.net mvc4 HttpPost null值

时间:2012-11-18 12:48:17

标签: c# asp.net .net razor http-post

使用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>
}

非常感谢你的帮助

2 个答案:

答案 0 :(得分:2)

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

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

此外,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。 UserGroup类,正如我想象的那样:

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已从ICollection更改为IList,因为我们需要按索引访问元素(请参阅视图代码)
  • 添加了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>
}

答案 1 :(得分:0)

另一个不需要大量隐藏字段的选项是简单地指定您希望将模型传递给控制器​​。我觉得这个更干净了。

@using(Html. BeginForm("action","controller", Model, FormMethod.Post)){
...
}