使用tempdata验证方法条目并通过控制器中的多个POST传递信息是一种不好的做法吗?备择方案?

时间:2012-07-12 15:54:13

标签: c# .net asp.net-mvc asp.net-mvc-3

首先,一些背景:

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

实施例: 1.在搜索字段中输入userID。 2.单击按钮,执行POST,通过我的存储库在数据库中找到用户,存储在TempData中的用户ID ,调用RedirectToAction(“编辑”)

TempData["user"] = searchViewModel.userID;
return RedirectToAction("Edit");
  1. 在编辑视图上执行编辑,单击提交按钮,用户信息存储在TempData中,调用RedirectToAction(“确认”);
  2. 显示在Confirm视图上进行的更改,单击“Confirm”,执行最终的HTTP POST并通过我的存储库服务进行更改。
  3. 这似乎运作良好。为了通过输入“../Edit/Confirm”来处理试图跳到地址栏中的页面的人,我在我的确认方法中进行了检查:

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

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

1 个答案:

答案 0 :(得分:1)

从第1步到第2步,我会建议采用一种参数化的行动:

  1. 在搜索字段中输入userID。
  2. 点击按钮,执行POST,通过我的存储库在数据库中找到用户
  3. 调用RedirectToAction(“编辑”,新{UserId = foundUserId})
  4. 此外,搜索时,您可能不应该进行POST。当你在寻找信息而不是改变信息时,GET就可以了。这样就可以完全避免使用tempdata的PRG模式,因为你执行的是GET而不是POST。

    至于确认,还有另一种方法可以在没有tempdata的情况下做到这一点。而不是重定向到您的确认操作,POST到它,并返回您的确认视图模型。只有在第二次POST之后,你才能点击回购并在POST后使用重定向完成PRG模式,最后获得Get。

    用户不应该为您的确认操作执行任何类型的GET,正如您的绑带可以看到的那样。所以,只是不允许获取。 POST从编辑表单到确认操作,返回一个视图,然后从该视图POST到第二个POST操作方法。由于这些都是同一过程的一部分,因此您不必处理重定向或tempdata,直到过程完成(repos更新)。

    更新(回复评论)

    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">。这是用于编辑数据的表单。
    4. 用户在(3)的表单视图中输入数据,然后单击“提交”。
    5. UsersController上的操作方法StillNeedsConfirmationAction接受带有viewmodel对象的HTTP POST。但是,该操作不是重定向,而是返回另一个视图,传递相同的viewmodel对象。
    6. (5)中返回的视图包含<form method="POST" action="/Users/ConfirmAndUpdateAction">。它将为您之前的POST表单中的每个文本框或其他表单元素呈现隐藏的输入。
    7. 用户点击第二个表单上的提交以确认字段
    8. 您的UsersController上的操作方法ConfirmAndUpdateAction接受具有与您的其他POST操作相同的viewmodel对象的HTTP POST。但是,这次不是返回另一个视图,而是将数据保存在存储库中并重定向。