MVC PRG 模式 - 传递模型

MVC PRG pattern - passing a model around

我在我的 MVC 项目中使用 PRG 模式 (Post-Redirect-Get)。这个想法是,您不会 return 从您的操作中查看,而是在成功时 POST 您完全重定向到另一个视图,该视图执行 Get(可能在数据库上)以取回保存的值并重新显示它们(想想 "Save Successful" 页面)。

就我而言,我没有数据库来保存保存的详细信息,我想知道一种可靠的存储方式,然后在下一页获取保存的详细信息。

我在做

RedirectToAction("Success", myViewModel)

我的理解是错误的,尤其是因为它具有 URL 栏中的所有值。我需要做的是

RedirectToAction("Success")

然后以某种方式取回值,构建视图模型并将其提供给视图。

我知道有 ViewBag、TempData、ViewData 和 Session,但没有在各种情况下进行大量测试,我不知道哪一个适合我的情况。静态对于面向 public 的网站显然没有好处。

如果在没有数据库的情况下做PRG,数据持久化的方式是什么?或者如果用户确实返回和转发,我可以简单地抛出某种错误并重定向吗?

非常感谢。

编辑:示例场景 - 汽车保险。用户访问站点,填写个人详细信息并点击提交。下一页显示了选项(第三方、盗窃、自愿超额等),选择它们后,将通过 AJAX 拨打电话以获取报价。

所有个人详细信息随选项一起发送。但是没有用户帐户,也没有任何内容写入数据库(数据保护法 - 除非获得许可,否则我们不会存储数据,如果他们只是浏览,询问会让他们失望)。

更新:我们确定的解决方案如下: 详细信息 POST 操作构建了一个 OptionsViewModel。它被放入 TempData。 RedirectToAction("Options") 被调用。 在 Options 操作中我们得到 viewmodel

OptionsViewModel viewModel = (OptionsViewModel)TempData.Peek("MyViewModel"); // .Peek preserves the value

如果 viewmodel 为 null,我们将 RedirectToAction() 返回到 Details。否则我们 return 选项视图。

除了它创建的难看的查询字符串之外,RedirectToAction("Success", myViewModel) 可能会失败,因为 (1) 您可能超过查询字符串限制(这会引发异常)或 (2) 如果您的模型包含以下属性复杂的对象或集合,这些属性将在 GET 方法中 null

ViewBagViewData 不适合在方法之间传递值 - 它们用于将数据从控制器传递到视图(参考 this article

不清楚为什么你没有某种永久存储,但如果没有它,你将需要 TempDataSession 在请求之间临时存储数据。

TempData 使用 Session 但它只持续一个请求,所以如果你用它来将模型传递给 Success() 方法,并且用户刷新浏览器,模型将是 null,尽管您可以使用 .Peek.Keep 来覆盖该行为(请参阅 this question/answer)。

就个人而言,我从不使用 Session(并且只使用 TempData 来传递非关键数据,例如指示成功的一次性消息)并且会考虑将数据保存在某个地方,例如保存到xml 重定向之前的文件,以便可以在 GET 方法中再次读取它。