对于从第 1 步到第 2 步,我建议改用参数化操作:
- 在搜索字段中输入用户 ID。
- 单击按钮,执行 POST,通过我的存储库在数据库中找到用户
- 调用 RedirectToAction("Edit", new {UserId = foundUserId})
此外,在搜索时,您可能不应该进行 POST。当您正在寻找信息而不是对其进行变异时,GET 就很好了。这在您使用 tempdata 的第一个地方完全避免了 PRG 模式,因为您执行的是 GET 而不是 POST。
至于确认,还有另一种没有临时数据的方法。与其重定向到您的确认操作,不如发布到它,并返回您的确认视图模型。只有在第二个 POST 之后,您才会点击 repos 并在 POST 之后通过 Redirect 和最后的 Get 完成 PRG 模式。
用户不应该能够为您的确认操作执行任何类型的 GET,正如您的创可贴可以看到的那样。因此,根本不允许获取。从编辑表单 POST 到确认操作,返回一个视图,然后从该视图 POST 到第二个 POST 操作方法。由于这些都是同一过程的一部分,因此在该过程完成(更新存储库)之前,您不必处理重定向或临时数据。
更新(回复评论)
1.) 如果我删除 SearchUser 函数上的 [HttpPost] 属性,视图上的搜索按钮如何知道要调用什么?
您的搜索按钮嵌套在<form>
HTML 元素中。您需要将表单的方法更改为 GET。如果该属性不存在,我相信 POST 是默认值。您的搜索按钮将保持不变,但表单会将用户输入的输入作为 HTTP GET 请求而不是 HTTP POST 提交:
<form method="GET">
...
<input type="submit" value="Search" />
</form>
2.)您能否澄清删除重定向以确认?我无法理解如何将重定向更改为 POST
很难向刚开始 Web 开发的人解释这一点,但本质上,每个重定向始终是一个 HTTP GET 请求。这就是为什么您必须将数据放入会话(tempdata 使用会话)以便在无状态请求之间维护它的原因。
基本上,这是您的工作流程:
- 用户输入搜索输入并点击提交
- (1) 中的搜索作为 GET 请求发送到某个操作方法,该操作方法返回一个视图。
- (2) 中返回的视图包含
<form method="POST" action="/Users/StillNeedsConfirmationAction">
带有附加输入元素的 a。这是将用于编辑数据的表单。
- 用户从 (3) 在表单视图中输入数据并单击提交。
- UsersController 上的操作方法 StillNeedsConfirmationAction 接受带有 viewmodel 对象的 HTTP POST。该操作不是重定向,而是简单地返回另一个视图,传递相同的视图模型对象。
- (5) 中返回的视图包含一个
<form method="POST" action="/Users/ConfirmAndUpdateAction">
. 它将为您之前的 POST 表单中的每个文本框或其他表单元素呈现隐藏的输入。
- 用户在第二个表单上单击提交以确认字段
- 您的 UsersController 上的操作方法 ConfirmAndUpdateAction 接受一个 HTTP POST,它与您的其他 POST 操作所做的视图模型对象相同。但是,这次它不是返回另一个视图,而是将数据保存在您的存储库中并重定向。