[翻译] ASP.NET MVC Tip #6 – 提交表单后如何进行重定向
摘要:在这个Tip中,Stephen Walther介绍了当提交表单后如需重定向,为何需要调用RedirectToAction方法进行重定向,而不是直接返回一个视图。
假设你正在用一个HTML表单从用户那里收集信息。该HTML表单是由名为HomeController.Create()的控制器action显示的,而数据提交到名为HomeController.New()的控制器action,它会将表单中的数据添加到数据库中。在表单数据提交后,你希望显示聚合统计结果(如图1)。
图1 - Results.aspx视图
在编写New()控制器action时有两种方法。在清单1中,New() action首先将表单数据提交到数据库(使用LINQ to SQL),然后调用RedirectToAction()将用户重定向到Results() action。在清单2中,New() action没有调用RedirectToAction()。而是直接从New() action返回Results.aspx视图。
清单1 - SurveyController.vb

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

清单2 - Survey2Controller.vb

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

因此,在提交表单数据后,有两种方式可以显示结果页。既可以返回RedirectToAction(),也可以返回View()。究竟哪种更好一些呢?
当你调用RedirectToAction()时,ASP.NET MVC框架会导致Web浏览器产生一个新的重定向。RedirectToAction()方法向浏览器返回一个302 - Object Moved状态。然后浏览器会获取Results视图。
因此你可能会认为调用RedirectToAction()是一种不好的方式。在调用RedirectToAction()时浏览器会做更多的工作。当浏览器发起新的请求时网络可能会出现错误。实用RedirectToAction()增加了出错的可能性。
然而,有三个很好的原因可以表明RedirectToAction()要优于直接返回一个视图。两个原因是实际的,还有一个哲学上的原因。我们来从实际的原因开始。如果没有做重定向,而用户单击了浏览器的刷新/重新加载按钮,数据库的数据会被提交多于一次。换句话说,如果没有进行重定向,数据库表中可能会出现重复的数据。
现在,很多流行的浏览器会在遇到这种危险情况时向用户发出警告。Microsoft Internet Explorer 7.0提供了如图2所示的警告。因此,相对于过去而言,这种危险情况可能还不是最坏的。
图2 - IE在表单提交后的刷新提出的警告
第二个实际原因与第一个相关。如果你将结果页放在书签/收藏夹中(或通过Email将结果页链接发给朋友),并在之后用书签打开页面,数据操作会在没有提示的情况下发生。这会提交一个没有数据的表单,客户端验证将被忽略,你会得到如图3所示的丑陋页面:
图3 - 使用书签回到结果页
RedirectToAction()优于View()的第三个原因是哲学上的。ASP.NET MVC框架为你的应用程序提供了一个“静态”的界面。不同的URL代表了不同的操作。如果你在New()动作中返回了Results视图,动作和视图之间的这种对应关系就被破坏了。换句话说,在一个“静态”的应用程序中,你看到的视图应该和你在浏览器地址栏中看到的URL地址是对应的。
如果你在提交表单数据后调用了RedirectToAction(),你会在浏览器地址栏中看到Survey/Results这样的地址。如果你在表单提交后调用的是View(),你在浏览器地址栏中看到的地址时Survey/New。由于你看到的是Results页,第一种情形更有意义。浏览器的地址栏应该反映Web应用程序的状态。进行重定向可以保持浏览器和服务器之间的同步。
******** (原著作者的)更新 *********
在Microsoft工作最好的事情就是你周围总是围绕着一群非常聪明的人。在发表了这篇Blog之后,我跑进(以xUnit著称的)Brad Wilson的屋里,他告诉我这个Tip的主题中应用了一个模式。这个模式被称作PRG模式(Post-Redirect-Get模式)。这里是该模式在Wikipedia中的入口:
http://en.wikipedia.org/wiki/Post/Redirect/Get
因此,这篇Tip应该改名叫“在提交表单时使用PRG模式”。
此处下载源代码:http://weblogs.asp.net/blogs/stephenwalther/Downloads/Tip6/Tip6.zip。
-----
广告:[.NET正则表达式库] http://regex-lib.net/。
-----
声明:
原作者已撰写到Tip#18,对于进度的缓慢,老刘在这给您说声抱歉!另外,欢迎大家直接阅读原文。最后,骂人请登录。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步