首先,一些背景:
在我的 Controller 中,我在成功的 HTTP POST 上返回 RedirectToAction。我使用 TempData 保存用户输入的模型数据,以便我重定向到的方法可以再次使用此输入数据。
示例: 1. 在搜索字段中输入用户 ID。 2. 单击按钮,执行 POST,通过我的存储库在数据库中找到用户,用户 ID 存储在 TempData 中,调用 RedirectToAction("Edit")
TempData["user"] = searchViewModel.userID;
return RedirectToAction("Edit");
- 在编辑 View 中进行编辑,点击提交按钮,用户信息存储在TempData中,调用RedirectToAction("Confirm");
- 在“确认” View 中显示所做的更改,单击“确认”,执行最终的 HTTP POST 并通过我的存储库服务进行更改。
这似乎运作良好。为了处理人们试图通过键入“../Edit/Confirm”跳到地址栏中的页面,我在我的Confirm方法中进行了此检查:
if (TempData["editUserViewModel"] == null)
return RedirectToActionPermanent("Edit");
这是处理地址栏输入的最佳方式吗?我还执行 TempData.Keep("editUserViewModel") 以便刷新工作。这是处理刷新的最佳方式吗?
最佳答案
对于从步骤 1 到步骤 2,我建议改为参数化操作:
- 在搜索字段中输入用户 ID。
- 单击按钮,执行 POST,通过我的存储库在数据库中找到用户
- 调用 RedirectToAction("Edit", new {UserId =foundUserId})
此外,在搜索时,您可能不应该执行 POST。当您查找信息而不改变信息时,GET 就可以了。这在您使用临时数据的第一个地方完全避免了 PRG 模式,因为您执行的是 GET 而不是 POST。
至于确认,还有另一种无需临时数据的方法。不要重定向到您的确认操作,而是发布到它,并返回您的确认 View 模型。只有在第二个 POST 之后,您才能访问存储库并在 POST 之后通过重定向和最后的 Get 完成 PRG 模式。
用户不应该能够对您的确认操作执行任何类型的 GET,正如您的创可贴所显示的那样。所以,根本不允许获取。从编辑表单 POST 到确认操作,返回一个 View ,然后从该 View POST 到第二个 POST 操作方法。由于这些都是同一流程的一部分,因此在流程完成(存储库更新)之前,您不必处理重定向或临时数据。
更新(回复评论)
1.) 如果我删除 SearchUser 函数上的 [HttpPost] 属性, View 上的搜索按钮将如何知道要调用什么?
您的搜索按钮嵌套在 <form>
中HTML 元素。您需要将表单的方法更改为 GET。如果该属性不存在,我相信 POST 是默认值。您的搜索按钮将保持不变,但表单会将用户输入的输入作为 HTTP GET 请求而不是 HTTP POST 提交:
<form method="GET">
...
<input type="submit" value="Search" />
</form>
2.) 您能否澄清一下删除重定向以确认的情况?我无法理解如何将重定向更改为 POST
很难向刚开始 Web 开发的人解释这一点,但本质上,每个重定向始终都是 HTTP GET 请求。这就是为什么您必须将数据放入 session 中(tempdata 使用 session )以便在无状态请求中维护它。
基本上,这是您的工作流程:
- 用户输入搜索内容并点击提交
- (1) 中的搜索作为 GET 请求发送到某个操作方法,该方法返回一个 View 。
- (2) 中返回的 View 包含
<form method="POST" action="/Users/StillNeedsConfirmationAction">
带有附加输入元素。这是将用于编辑数据的表单。 - 用户在 (3) 的表单 View 中输入数据并点击“提交”。
- UsersController 上的操作方法 StillNeedsConfirmationAction 接受带有 viewmodel 对象的 HTTP POST。该操作只是返回另一个 View ,传递相同的 View 模型对象,而不是重定向。
- (5) 中返回的 View 包含
<form method="POST" action="/Users/ConfirmAndUpdateAction">
。它将为您之前的 POST 表单中的每个文本框或其他表单元素呈现隐藏的输入。 - 用户点击第二个表单上的“提交”以确认字段
- UsersController 上的操作方法ConfirmAndUpdateAction 接受 HTTP POST,其 View 模型对象与其他 POST 操作所执行的 View 模型对象相同。不过,这次它不会返回另一个 View ,而是将数据保存在存储库中并进行重定向。
关于c# - 使用 tempdata 验证方法条目并通过 Controller 中的多个 POST 传递信息是否是一种不好的做法?备择方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11455772/