简体   繁体   English

ASP.NET MVC-跨视图传递数据

[英]ASP.NET MVC - Passing data across Views

I'm building an MVC application. 我正在构建一个MVC应用程序。 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. 我设置了一个类似视图的“向导”,使用户可以填充不同种类的数据,直到操作结束为止,总共需要7个步骤。

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. 首先,我使用老式的Session并且所有内容都可以在台式机上使用,但是当我最终将应用程序部署到公司的托管服务器中时,我却遇到了异常,因为在某些步骤中Session随机擦除Session

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. 现在,我对所有内容进行了修改,以在TempData设置所需的任何数据,并在每一步中刷新所有数据,看来一切正常。

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 . 我对所有这些结构感到困惑:会话(我知道它来自asp.net), ViewDataTempData和神奇的ViewBag

I read a lot about but I need someone that clearly tell me what is more appropriate for me in this case. 我读了很多书,但是我需要一个清楚地告诉我在这种情况下更适合我的人。

I'd say the ViewBag is perfect for something like this. 我想说ViewBag非常适合这样的事情。 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> 现在,您将ViewBag称为“ Magic”视图包,但实际上它只是包装了ViewData,它是<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. ViewBag的工作方式是,它只是围绕ViewData的动态包装,因此,当您要求某些内容时,例如说ViewBag.ShoppingCart,它基本上会询问基础词典是否有一个名为“ ShoppingCart”的条目,然后返回该项目。

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. UPDATE问题是我不记得ViewBag和ViewData是特定于视图的,因此每当您单击其他View / Action时,它们都会被清空。

Unless you need the ShoppingCart (or wizard-progress) to be stored in a database, I'd go for ViewBag TempData in your case :) 除非您需要将ShoppingCart(或向导进程)存储在数据库中, 否则 我会选择 ViewBag TempData :)

You could also take a look at this article from Rachel Apple for a bit more info on the three: 您还可以查看Rachel Apple的这篇文章,以获取有关这三个方面的更多信息:

http://rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp.net-mvc-3-applications http://rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp.net-mvc-3-应用程序

(Ps. I'd recommend reading the comments as well on that post to get some more unbiased opinions) (注:我建议您也阅读该帖子的评论,以获得更多公正的见解)

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. 运行一个简单的测试:将您的会话提供程序更改为SQL,禁用隐藏的字段,然后查看您的应用程序是否正常运行。 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? 该应用程序是否应该在负载均衡器后面的Web场/“云”中运行? If so, you either have to: 如果是这样,您要么必须:

  • change the session provider to something else: SQL, StateServer, memcache, etc. Not many code changes required. 将会话提供程序更改为其他内容:SQL,StateServer,内存缓存等。不需要进行很多代码更改。

http://msdn.microsoft.com/en-us/library/ms178587.aspx and http://memcachedproviders.codeplex.com/ http://msdn.microsoft.com/zh-CN/library/ms178587.aspxhttp://memcachedproviders.codeplex.com/

OR 要么

  • re-design your wizard steps and reduce your dependency on shared values between views. 重新设计向导步骤,减少对视图之间共享值的依赖。 Session ID is all you need and you can query the DB for anything else. 会话ID就是您所需要的,您可以查询数据库其他内容。 Not very fast but safe and stable. 不是很快,但安全稳定。

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 . 优化:根据需要使用尽可能多的隐藏字段,以减少数据库查询的数量(如我所说,这没错),但是通常一个字段足以保持请求之间的序列化状态: 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. 即使您不必担心应用程序的多个实例(在不同的计算机上),IIS也会不时地回收工作进程。 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! 希望能帮助到你!

You have several options here: Use session, viewdata (or viewbag) but need to pass it using hidden fields or cookies. 您在此处有几个选项:使用会话,视图数据(或视图包),但需要使用隐藏字段或cookie传递它。

Viewdata has the problem that will give more work. Viewdata存在将进行更多工作的问题。

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). 使用为所有服务器保留会话的服务器或使用cookie(如果信息不是很关键)来解决此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM