我在我的MVC项目中使用PRG模式(Post-Redirect-Get)。我们的想法是,你不会从你的行动中返回一个视图,而是在成功的POST中返回你完全重定向到另一个视图,它可以获取(可能在数据库中)获取已保存的值并重新显示它们(想想a"保存成功"页面。)
在我的情况下,我没有数据库来保存已保存的详细信息,我想知道一种可靠的存储方式,然后在下一页上获取已保存的详细信息。
我在做
RedirectToAction("Success", myViewModel)
我明白这是错误的,尤其是因为它具有URL栏中的所有值。我需要做的是
RedirectToAction("Success")
然后以某种方式将值取回,构建一个viewmodel并将其提供给视图。
我知道有ViewBag,TempData,ViewData和Session但在各种情况下没有经过大量测试我不知道哪一个是我的情况所使用的。静态显然对面向公众的网站没有好处。
如果您在没有数据库的情况下进行PRG,那么保留数据的方法是什么?或者我可以简单地抛出某种错误&如果用户确实返回&重定向转发?
非常感谢提前。
编辑:示例场景 - 汽车保险。用户访问网站,填写个人详细信息并点击提交。在下一页显示选项(第三方,盗窃,自愿超额等),并在选择它们时通过AJAX进行调用以获得报价。
所有个人详细信息都会随选项一起发送。但是没有用户帐户,也没有任何内容写入数据库(数据保护法 - 除非获得许可,否则我们不会存储数据,如果他们只是浏览就会让人们关闭)。
更新:我们解决的解决方案如下: 详细信息POST操作构建一个OptionsViewModel。它被放入TempData。 调用RedirectToAction("选项")。 在Options操作中,我们获得了viewmodel
OptionsViewModel viewModel = (OptionsViewModel)TempData.Peek("MyViewModel"); // .Peek preserves the value
如果viewmodel为null,我们将RedirectToAction()返回到Details。否则我们返回选项视图。
答案 0 :(得分:1)
除了它创建的丑陋的查询字符串之外,RedirectToAction("Success", myViewModel)
可能会失败,因为(1)您可能超出查询字符串限制(这将引发异常)或(2)如果您的模型包含属于复杂对象的属性或者集合,这些属性在GET方法中将是null
。
ViewBag
和ViewData
不适合在方法之间传递值 - 它们用于将数据从控制器传递到视图(请参阅this article)
不清楚为什么你没有某种类型的永久存储,但没有它,你需要TempData
或Session
来临时存储请求之间的数据。
TempData
使用Session
但它只会持续一个请求,因此如果您使用它将模型传递给Success()
方法,并且用户刷新浏览器,则模型将是null
,但您可以使用.Peek
或.Keep
覆盖该行为(请参阅this question/answer)。
就个人而言,我从不使用Session
(并且仅使用TempData
来传递非关键数据,例如一次性消息表示成功)并且会考虑将数据保存在某处,例如xml文件在重定向之前,可以在GET方法中再次读取它。