在MVC4中创建Child对象 - 未将父信息传递给Create()控制器

时间:2013-02-17 02:52:56

标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-4

我有以下[HttpGet] Create()方法:

    public ActionResult Create(int? parentId)
    {
        var model = new CreatePersonViewModel();

        // pull parent from db
        var parent = _db.Persons.FirstOrDefault(s => s.Id == parentId);

        model.Parent = parentSet;

        return View("Create", model);
    }

如果我正在从另一个人的详细信息页面创建一个新人员,我会传入该父人员的ID,然后构建一个包含父项的viewModel。

POST看起来像这样:

 [HttpPost]
    public ActionResult Create(CreatePersonViewModel viewModel)
    {
        if (ModelState.IsValid)
        {

            var parent = viewModel.Parent;  // This is always null for some reason

            var person = new Person() { Name = viewModel.Name };

            // if it has a parent, build new relationship
            if (parent != null)
            {
                person.Parent = parent;
                parent.Children.Add(person);
            };

            _db.Save();

            return RedirectToAction("detail", "person", new { personId = person.Id });
        }
        return View(viewModel);
    }

由于某种原因,viewModel被推回到POST方法永远不会包含在GET控制器方法中定义的Parent。我如何告诉MVC将父级从GET推送到POST,而不会使用隐藏字段混淆视图?

如果有帮助,我的观点就在这里:

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>CreatePersonViewModel</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

2 个答案:

答案 0 :(得分:2)

控制器操作只会接收HTML表单中明确包含的数据。

如果您想接收Parent对象,则需要将其隐藏在隐藏的<input>标记中。

请注意,来自客户端的任何数据都完全由您的攻击者控制,并且无法信任。

答案 1 :(得分:0)

网络是无状态的,那么服务器如何知道您希望在幕后传递哪些数据?

您可以使用TempData传递数据,它将保留在服务器上,直到您的下一个请求读取它为止。但是我不认为你需要这个。由于您没有使用除父ID和名称之外的任何内容,因此将其存储在客户端上 - 即您的viewmodel仅包含那些字段 - viewmodel中没有实体。

当您发布到服务器加载您的父级时,请分配一个新子级并保存它。将整个对象发送给客户端是没有意义的。

此外,我还会在服务器上验证当前用户是否可以访问这些记录 - 如果适用,除非您的应用程序允许所有用户访问所有人员。