2

首先,一些背景:

在我的控制器中,我在成功的 HTTP POST 上返回 RedirectToAction。我使用 TempData 保留用户输入的模型数据,以便我重定向到的方法可以再次使用此输入数据。

示例: 1. 在搜索字段中输入用户 ID。2.点击按钮,执行POST,通过我的repository在数据库中找到用户,userID存储在TempData中,调用RedirectToAction("Edit")

TempData["user"] = searchViewModel.userID;
return RedirectToAction("Edit");
  1. 在Edit视图上进行编辑,点击commit按钮,用户信息保存在TempData中,调用RedirectToAction("Confirm");
  2. 显示在确认视图上所做的更改,单击“确认”,执行最终的 HTTP POST,并通过我的存储库服务进行更改。

这似乎运作良好。为了处理试图通过键入“../Edit/Confirm”来跳到地址栏中的页面的人,我在我的 Confirm 方法中进行了此检查:

if (TempData["editUserViewModel"] == null)
  return RedirectToActionPermanent("Edit");

这是处理地址栏输入的最佳方式吗?我也做 TempData.Keep("editUserViewModel") 以便刷新工作。这是处理刷新的最佳方式吗?

4

1 回答 1

2

对于从第 1 步到第 2 步,我建议改用参数化操作:

  1. 在搜索字段中输入用户 ID。
  2. 单击按钮,执行 POST,通过我的存储库在数据库中找到用户
  3. 调用 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. 用户输入搜索输入并点击提交
  2. (1) 中的搜索作为 GET 请求发送到某个操作方法,该操作方法返回一个视图。
  3. (2) 中返回的视图包含<form method="POST" action="/Users/StillNeedsConfirmationAction">带有附加输入元素的 a。这是将用于编辑数据的表单。
  4. 用户从 (3) 在表单视图中输入数据并单击提交。
  5. UsersController 上的操作方法 StillNeedsConfirmationAction 接受带有 viewmodel 对象的 HTTP POST。该操作不是重定向,而是简单地返回另一个视图,传递相同的视图模型对象。
  6. (5) 中返回的视图包含一个<form method="POST" action="/Users/ConfirmAndUpdateAction">. 它将为您之前的 POST 表单中的每个文本框或其他表单元素呈现隐藏的输入。
  7. 用户在第二个表单上单击提交以确认字段
  8. 您的 UsersController 上的操作方法 ConfirmAndUpdateAction 接受一个 HTTP POST,它与您的其他 POST 操作所做的视图模型对象相同。但是,这次它不是返回另一个视图,而是将数据保存在您的存储库中并重定向。
于 2012-07-12T19:04:36.300 回答