2

我有以下 [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);
    }

由于某种原因,被推回 POST 方法的 viewModel 永远不会包含在 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>
}
4

2 回答 2

2

控制器操作将仅接收明确包含在 HTML 表单中的数据。

如果你想接收 Parent 对象,你需要把它放在隐藏<input>标签中。

请注意,来自客户端的任何数据都在攻击者的完全控制之下,并且不可信。

于 2013-02-17T03:36:52.617 回答
0

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

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

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

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

于 2013-02-17T18:20:47.713 回答