ASP.NET MVC - 跨视图传递数据
我正在构建一个 MVC 应用程序。我的任务之一是建立一家商店。我设置了一个类似“向导”的视图集,让用户填写不同类型的数据,直到操作结束,总共 7 个步骤。
我的问题是如何在所有这些视图之间共享一些数据。
首先,我使用老式的 Session
并且一切都在我的桌面上运行,但是当我最终将应用程序部署到公司的托管服务器中时,我遇到了异常,因为 Session
在某些情况下被随机擦除步骤。
现在,我修改了所有内容以在 TempData 中设置我需要的任何数据,并在每个步骤中刷新所有数据,它似乎工作正常。
我有点困惑!
我对所有这些结构感到困惑:Session(我知道它来自 asp.net)、ViewData
、TempData
和神奇的 ViewBag
。
我读了很多相关内容,但我需要有人清楚地告诉我在这种情况下什么更适合我。
I'm building an MVC application. One of my taskS is to build a store. I set up a "wizard" like set of views that brings the user to fill different kind of data until the end of the operation, in total 7 steps.
My issue is about how to share some data between all these views.
First I used old-fashioned Session
and everything worked on my desktop, but when I finally deployed my application into my company's hosting server I got exceptions because Session
was erased randomly during some steps.
Now I modified everything to set up any data I need inside TempData
, and refreshing all data in each step and it's seems to work properly.
I'm a little confused!
My confusion is about all these structures: Session (I know it coming from asp.net), ViewData
, TempData
and the magic ViewBag
.
I read a lot about but I need someone that clearly tell me what is more appropriate for me in this case.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我想说 ViewBag 非常适合这样的事情。现在,您将 ViewBag 称为“Magic” viewbag,但实际上它只是包装了 ViewData,ViewData 是
的字典ViewBag 的工作方式是:只是 ViewData 的动态包装器,因此当您请求某些内容(例如 ViewBag.ShoppingCart)时,它基本上会询问底层字典是否有名为“ShoppingCart”的条目,然后返回该项目。
更新 问题是我不记得 ViewBag 和 ViewData 是特定于视图的,因此每当您点击不同的视图/操作时它们就会被清空。
除非您需要将 ShoppingCart (或向导进度)存储在数据库中,否则我会在您的情况下使用
ViewBagTempData :)您还可以查看 Rachel Apple 的这篇文章关于这三个的更多信息:
http://rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp.net-mvc-3-applications
(Ps.我建议阅读该帖子的评论以获得一些更公正的意见)
I'd say the ViewBag is perfect for something like this. Now, you're referring to the ViewBag as a "Magic" viewbag, but in reality it just wraps the ViewData which is a dictionary of
<string,object>
The way the ViewBag works is that it's just a dynamic wrapper around the ViewData, so when you ask for something, let's say ViewBag.ShoppingCart, it basically ask the underlying dictionary if it has an entry called "ShoppingCart", and returns the item.
UPDATE Problem is I didn't remember that ViewBag and ViewData is view-specific, so they're emptied whenever you hit a different View/Action.
Unless you need the ShoppingCart (or wizard-progress) to be stored in a database, I'd go for
ViewBagTempData in your case :)You could also take a look at this article from Rachel Apple for a bit more info on the three:
http://rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp.net-mvc-3-applications
(Ps. I'd recommend reading the comments as well on that post to get some more unbiased opinions)
使用隐藏字段并没有什么问题——至少在我的书中是这样。
我会“修复”会话问题,而不是尝试围绕该问题编写代码。运行一个简单的测试:将您的会话提供程序更改为 SQL,禁用隐藏字段并查看您的应用程序是否正常工作。如果没有,您还需要担心其他(更大的)问题。
这个应用程序应该在网络场/“云”/负载平衡器后面工作吗?如果是这样,您必须: 将会话
http://msdn.microsoft.com/en-us/library/ms178587.aspx 和 http://memcachedproviders.codeplex.com/
或者
优化:使用尽可能多的隐藏字段来减少数据库查询的数量(就像我说的,这没有错),但通常一个字段足以在请求之间保持序列化状态: http://blog.maartenballiauw.be/post/2009/10/08/Leveraging-ASPNET-MVC-2-futures-ViewState.aspx。
即使您不必担心应用程序的多个实例(在不同的计算机上),IIS 也会时不时地回收工作进程。当这种情况发生时,您最终可能会在同一台计算机上同时运行两个实例(运行很短的时间),而您的某些用户可能会不幸地在这些时刻恰好访问了服务器。
如果下一个请求命中应用程序的不同实例,那也没关系。始终尝试以这个目标进行设计。
希望有帮助!
Nothing wrong with using hidden fields - in my book, at least.
I'd 'fix' the Session issue instead of trying to write code around the problem. Run a simple test: change your Session provider to SQL, disable the hidden fields and see if your app works properly. If it doesn't, there are other (bigger) issues you have to worry about.
Is this app supposed to work in a web farm / "cloud" / behind a load-balancer? If so, you either have to:
http://msdn.microsoft.com/en-us/library/ms178587.aspx and http://memcachedproviders.codeplex.com/
OR
Optimize: Use as many hidden fields as you like to reduce the number of DB queries (like I said, nothing wrong with this) but usually one field is enough to keep your serialized state between requests: http://blog.maartenballiauw.be/post/2009/10/08/Leveraging-ASPNET-MVC-2-futures-ViewState.aspx.
Even if you don't have to worry about multiple instances of your app (on different machines), IIS recycles the worker processes every now and then. When it does, you can end up with two instances running at the same time (for small amounts of time) on the same machine and some of your users might be unlucky enough to hit the server exactly during those moments.
It should not matter if the next request hits a different instance of your application. Always try to design with this goal in mind.
Hope it helps!
您在这里有多种选择:
使用session、viewdata(或viewbag)但需要使用隐藏字段或cookie来传递它。
Viewdata 存在的问题会带来更多的工作量。
我会继续会话,但在您的情况下它可能会被清除,因为您可能有多个服务器,并且当第二个请求到达另一台服务器时,它不会包含上一步中的数据。
使用保存所有服务器会话的服务器或使用 cookie(如果信息不重要)来解决此问题。
You have several options here:
Use session, viewdata (or viewbag) but need to pass it using hidden fields or cookies.
Viewdata has the problem that will give more work.
I'd go with the session but maybe it gets cleared in your case because you probably have more than one server and when the 2nd request gets to another server, it just won't have the data from the previous step.
Solve this problem using a server that holds the session for all servers or use cookies (if the information is NOT critical).