ASP.NET MVC-TempData-好的或坏的做法


96

我正在使用AcceptVerbsScott Gu的Preview 5博客文章中详细介绍的方法来处理ASP.NET MVC中的表单项:

  • 用户通过GET获取一个空表格
  • 用户通过POST将填写的表单过帐到同一操作
  • 该操作将验证数据,采取适当的操作并重定向到新视图

因此,我不必使用TempData。也就是说,我现在必须在此过程中添加一个“确认”步骤,并且似乎需要使用TempData

出于某种原因,我不愿意使用TempData它,这是需要设计的东西。

这完全是一个有效的问题,还是我要弥补?


1
考虑使您的“确认”步骤成为JavaScript对话框。服务器往返次数更少,您将不会遇到此问题。
ajma

Answers:


26

我认为临时数据是通知用户的一劳永逸的机制。提醒他们最近所做的事情真是太好了,但我也很犹豫将其设置为某些用户流程中的必需步骤。原因是如果他们刷新页面,我相信它将消失。好吧,我想我也很犹豫使用它,因为它的定义不是很可靠。

我想知道问题是否出在确认步骤之前,您是否将操作重定向到另一个页面。我想知道在他们第一次提交后,是否可以进行足够的处理以生成确认对话框,然后返回带有确认问题的原始页面。类似于您执行验证的方式,除了验证规则检查是否执行了确认步骤(隐藏确认UI直到其他验证通过)。


77

不需要厌恶TempData ...但是,如果使用不正确,肯定会表明设计不佳。如果您使用的是RESTful URL,则TempData是将消息从POST操作传输到GET操作的最佳实践。考虑一下:

您在URL产品/新建处有一个表格。张贴到产品/创建表单,该表单验证表单并创建产品,成功后,控制器将重定向到URL产品/ 1,错误时将重定向回产品/新建以显示错误消息。

Products / 1只是产品的标准GET操作,但我们希望显示一条消息,指示插入成功。TempData非常适合此操作。将消息添加到Post Controller中的TempData,然后在视图中放入一些if逻辑,然后完成。

失败时,我一直将在FormCollection中输入的值和错误消息的集合添加到Post Action中的TempData中,并重定向到初始Action Prodcuts / New。我已经在视图中添加了逻辑,以使用先前输入的值以及任何错误消息填充表单输入。对我来说似乎很干净!


当您可以直接回发到时,为什么还要做这些额外的工作Products/New?会Products/Create增加什么价值?
mpen 2011年

2
@Mark使用Products / Create可以防止用户通过回发来完成操作,然后在稍后刷新(或添加书签并返回)时意外地重新完成操作的情况。有关更多信息,请参见en.wikipedia.org/wiki/Post/Redirect/Get
ehdv

2
@ehdv:但是真的吗?成功时,它会重定向到另一页;失败时,它应该显示表单错误,并且不应采取任何措施,因此不会造成危害。这只会阻止令人讨厌的“您确定要重新发布”消息,这是我经常想要的。我想这取决于您的设计,所以我可以理解您的观点。
mpen 2011年

31

我认为您在使用TempData之前一定要犹豫。TempData存储在会话中,如果发生以下情况,这可能对您有影响:

  1. 您现在不在网站上使用会话
  2. 您有一个需要扩展到高吞吐量的系统,即,您希望完全避免会话状态
  3. 您不想使用cookie(我不知道MVC现在如何支持无cookie会话)

如果您的站点需要具有高可用性,那么在应用会话状态方面还有其他注意事项,但这都是可以解决的问题。


16
尽管TempData是默认提供程序,但不必将其存储在会话中-这可能就是为什么它不在方法doc中的原因。还有一个cookie提供程序,作为如何编写自定义提供程序的示例。
FinnNk

3

我有一个GetModel方法,该方法首先检查TempData [“ model”]并将其返回。否则,GetModel将从数据库中加载适当的数据。

当我有一个需要返回需要相同模型数据的不同视图的操作时,它将节省数据库的额外负担。


是的,我遇到了这个问题:(1)验证记录是否存在,如果有效,请重定向到页面(2)加载记录以显示给用户。因此,数据库将被命中以进行验证和显示。我几乎为此使用TempData,但感觉就像检查意见。我喜欢您的方法来包含它。
匿名

在这种情况下,最好使用适当的缓存机制。
nicodemus13 2014年

3

在MVC3中检出无会话控制器。事实证明,使用会话会阻止并行执行单个用户的请求,从而导致性能下降。

由于tempdata默认使用会话,因此您将无法使用此功能。您可以切换到对临时数据使用cookie,但这有点尴尬(至少对我而言)。不过,它仍然比viewstate干净,因此也许不是一个大问题。


2
您对无会话控制器和TempData使用会话是正确的。可是等等!会话不是一件坏事,您可以将Sessionless与Session控制器混合使用。当您(从浏览器)对服务器进行大量AJAX调用时,您确实需要Session_less_控制器。当您一次只触碰一页时,您不需要保持会话状态。实际上,这不会给您带来任何好处……因为您只需要一次点击服务器即可。因此可以混合搭配。
Pure.Krome

2

你为什么这么讨厌?这东西只是简单地做好工作:)

如果您不喜欢它,因为它的类型不是很严格,那么您可以随时对其进行包装,从而为您提供强类型的界面。


2

就像使用ViewData一样,这意味着可能没有安全风险。但是我宁愿使用ViewData而不是TempData。在这里检查比较:http ://www.squaredroot.com/2007/12/20/mvc-viewdata-vs-tempdata/

根据设计的不同,您始终可以将用户/购物篮或所需的任何内容存储在数据库中的tempdata中,并且仅具有“ IsReady”字段,该字段指示其是否已完成,从而使其可扩展,以备以后使用。请注意,人们可以关闭其浏览器。


2
注意:您链接到的文章是最新的,但仅适用于MVC1。在MVC2中,TempData发生了相当大的变化。
mikemanne 2011年

@mikemanne,是的。但是答案是从2008年末开始的。但是也许答案应该更新?
Filip Ekberg

0

所有的好答案,您是否已看过传递消息的方法。

由于大多数会话都存储在内存中,因此TempData和Session并不是RESTful架构的最佳主意。因此,当您要使用服务器场时,用户会话将在一台服务器上存在,而他们的下一个请求可以发送到另一台服务器。

话虽如此,请看一下TempData在此处用于传递消息的用法。

http://jameschambers.com/2014/06/day-14-bootstrap-alerts-and-mvc-framework-tempdata/

Mabye如果仅用于重定向到另一个页面警报,则可以适合使用查询字符串方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.