MVC 中是否有最佳实践和推荐的 Session 变量替代方案 [英] Is there a best practice and recommended alternative to Session variables in MVC

查看:27
本文介绍了MVC 中是否有最佳实践和推荐的 Session 变量替代方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,首先,在有人试图确定这是一个重复"问题之前;我已经查看了关于类似问题的大多数关于 SO 的帖子,但即使结合所有已经说过的内容,我仍然有些进退两难,以求最终确定,或者我应该对此表示一致同意.

Okay, so first off before anyone attempts to make a determination that this is a "duplicate" question; I have reviewed most of the posts on SO regarding similar questions but even in combination of all that has been said I still am somewhat at a dilemma as to the definitive or maybe I should say unanimous agreement on this.

然而,我可以说我(根据帖子)最终确定答案是基于要求的范围.但即使考虑到这一点,我的意见似乎过于多样化,我无法决定我应该如何处理.

I can however say that I have (based on the posts) conclusively determined that the answer is based on the scope of the requirement. But even with consideration of this, the opinions seem too diverse for me to make a decision as to how I should handle this.

我的直接要求是我需要在多个视图中保存来自 1 个控制器的变量数据.更具体地说,我有一个控制器和相应的视图来处理购物车项目计数,我想在多个视图中保留该数据.我认为 _layout 视图是最合乎逻辑的选择.

My immediate requirement is that I need to persist variable data from 1 controller across many views. More specifically, I have a controller and corresponding view that handles shopping cart item counts and I would like to persist that data across multiple views. I am thinking that the _layout view is the most logical choice for this.

现在我通过将值分配给从我的 _layout 视图中检索到的 Session 变量成功地完成了这项任务;因此,即使用户要浏览网站内的任何位置,购物车中的商品数量也会一直存在,直到他们离开网站或完成结帐;在这种情况下,变量将在代码中被清除.

Now I have successfully accomplished this task by assigning the value to a Session variable which is retrieved from my _layout view; so even when the user were to navigate any where within the site the number of items in the Shopping Cart will persist until either they leave the site or complete the checkout; in which case the variable will be cleared in code.

我读过的帖子似乎偏向于远离 Session 变量而支持 Cookies 并将数据存储在数据库中;或者说出于我建议使用它们的目的,会话变量非常适合使用.

The posts I've read seemed biased to either staying away from Session variables in favor of Cookies and storing data in a database; or stating that for the intent purpose for which I propose to use them, Session variables are perfectly fine to use.

我读过的另一件事表明,由于信息存储在服务器上,因此如果站点上的流量很高,会话变量可能会影响整体性能.

The other thing I've read suggests that Session variables can potentially impede overall performance if there is high traffic on the site since the information is stored on the server.

我个人无法证明将此类信息存储在数据库中并随后访问数据库是合理的,因为我认为这也会影响站点性能,并且对于存储临时数据似乎有点过头了.TempData、ViewData 和 ViewBag 无法持久保存数据,因此它们不是 IMO 要求的逻辑选择.

I personally cannot justify storing this type of information in a database and subsequently hitting the database as I'd imagine that this could also affect site performance and seems a bit overkill for storage of temporary data. TempData, ViewData and ViewBag do not work in persisting the data so they are not logical choices for the requirement IMO.

如果有另一种非常适合的替代 Session 变量(对我有用),我想知道它是什么.

If there is another well suited alternative to the Session variable (which is working for me) I would like to know what it is.

在提供最佳推荐方面似乎自相矛盾的 2 个帖子让我有点困惑.

2 posts that seem contradictory in effort of providing best recommendations leave me a bit confused.

缺点:在 ASP.NET MVC 中避免使用会话状态是一个好习惯吗?如果是,为什么以及如何?

优点:仍然可以在 ASP.NET mvc 中使用会话变量,或者对于某些东西(例如购物车)是否有更好的选择

似乎这个问题(尽管有许多不同的变体)没有我可以得出结论的明确答案.

Seems that this question (although presented in many different variations) has no definitive answer that I can conclude.

如果有更可取的方法来实现这一点而不会矫枉过正,那么这就是我正在寻找的答案.

If there is a more preferrable way to accomplish this without overkill then that is the answer I'm in search of.

我在某处阅读了 MVC 过滤器的使用以及 Global.ascx 应用程序启动部分,但这似乎不适合在控制器级别设置的变量,以及静态变量.

I read somewhere the use of MVC filters in tandem with the Global.ascx application start section as well, but this does not seem appropriate for variables set at the controller level as much as perhaps, static variables.

有人可以压制(因为没有更好的词)关于该主题的许多不同意见,并可能对问题提供更明确的答案吗?我敢肯定,不同的意见有其一席之地,我并不试图诋毁他们.但是有一个明确的、可能是一致的答案会更好;然后我可以对其他帖子进行分类,以确定最适合我的应用程序的内容.

Can someone maybe squash (for lack of a better word) the many diverse opinions on the topic and maybe provide a more definitive answer to the question? I'm sure the diverse opinions have their place and I'm not attempting to discredit them. But having a definitive and possibly unanimous answer would be better; then I could sort through the other posts to determine what is best for my application.

当然,如果这个问题没有确定的答案;告诉我,我会尝试从其他帖子中得出我自己的答案.

Of course, if this question has no definitive answer; just tell me that and I'll attempt to derive my own answer from the other posts.

谢谢

==========================================================

===========================================================

缓存和 Cookie 似乎是响应中的普遍偏好,但我也注意到缓存不是跨多个网络服务器使用的理想选择,因为同步可能是一个潜在的问题.

Caching and Cookies seem to be a general preference from the responses however I've also noted the statement that caching its not an ideal candidate to use across multiple web server because synchronization can be a potential issue.

感谢 Tim,据说数据库存储已经过优化,用户可以选择稍后返回并从上次停止的地方继续.

Giving credit to Tim, it's stated that Database storage is optimized and users have the option to return at a later time and continue where they left off.

这是一个很好的观点,但要对概率保持前瞻性;鉴于某些用户可能不会返回而在数据库中留下不需要的数据,这可能是合理的.

That is an excellent point, but keeping foresight on probabilities; its likely a reasonable given that some users may not return leaving unneccessary data in the database.

因此,保持数据库优化和清洁(对我来说"同样重要)需要实施维护任务,以根据设定的时间阈值自动使这些记录过期,以解决这些情况.虽然维护任务不是一个毫无疑问的选择,但我仍然认为这只是为了作为临时存储的目的而为任务增加了一点工作.

So keeping the DB optimized and clean (which "to me" is of equal relevance) would require implementing a maintenance task to automatically expire those records based on a set threshold of time to account for those circumstances. Although a maintenance task is not an unquestionable option, I still think this adds just a bit more work to the task simply for the intent purpose of serving as temporary storage.

尽管如此,我确实尊重蒂姆的建议,并相信在一定程度上反驳我最初的意见是值得的;数据库似乎不是存储临时数据的可行选择;所以我认为妥协是在结账后将数据存储在数据库中(考虑到购物车或类似的场景).通过这种方式,如您之前所述,后续访问时可能会持续跟踪数据,以便您拥有交易记录.但更重要的是,那些真正相关的交易数据才能持久化到数据库中.

Nonetheless, I do respect Tim's recommendation and believe it deserves merit on countering my initial opinion to a degree; that a database would not seem to be a viable option for storing Temporary data; so I think the compromise would be to store the data in a database (given the scenario of a Shopping Cart or similar) perhaps after a checkout. This way as you previously stated, the data may be persistently tracked upon subsequent visits so you have a record of transactions. But more importantly, it would be data of those transactions having real relevance to persist to the database.

也有人说虽然Session比Database快;但尽管有其警告,在某种程度上可以通过其他机制(例如利用 SessionStateBehavior 属性)来缓解,仅作为一个示例.

It was also stated that although Session is faster than Database; but notwithstanding to have its caveats that can to some degree be mitigated by other mechanisms such as leveraging the SessionStateBehavior attribute, just serving as one example.

但是......我认为埃里克通过邓宁 - 克鲁格效应将这一点带回家.虽然,从这里给出的建议答案的内容和解释;我严重怀疑任何做出回应的人的专业知识是否有任何问题.尽管如此,我倾向于同意这样一个事实,即获得一致意见可能比我的合理预期要高一些.

BUT... I think Erik kind of drove the point home with the Dunning-Kruger Effect. Although, from the content and explanations for proposed answers given here; I seriously doubt the expertise of any of the individuals who have responded is any way questionable. Nonetheless, I tend to agree on the fact of getting a unanimous opinion may be somewhat of a higher than reasonable expectation on my part.

我更具体地寻找的是对一种可以轻松适应多种场景的技术的普遍共识.换句话说,它不仅可以适应我的特定场景,而且还可以为具有潜在更重流量的更大环境提供可扩展性元素.通过这种方式,编程中的更改要么完全缓解,要么充其量最小.

What I was more specifically looking for was a general consensus for a technique that would comfortably accomodate a diverse number of scenarios. In other words, something that would accomodate not only my particular scenario but also provide the element of scalability to larger environments with potentially heavier traffic. This way a change in the programming would be either alleviated altogether or minimal at best.

=================================================

==================================================

  1. 会话变量似乎适用于较小的案例场景,并且在适用时,但它们有一些潜在的持久性问题以及 Erik 非常详尽地陈述的其他显着差异.所以这个选项显然不适合可扩展的模型.

  1. Session variables seem to accomodate smaller case scenarios and when applicable, but they have some potential for persistence concerns among other notable discrepancies as stated very thorougly by Erik. So this option obviously will not fit a scalable model.

缓存比会话变量更可取,但也不一定是最佳"可扩展选项,因为除其他外,正如前面指出的那样,Web 服务器群环境中潜在的同步复杂性.但仍然是一个选择.

Caching is preferable over Session variables but again not neccessarily the "best" scalable option due to among other things to the potential synchronization complexities in web server farm environments as previously pointed out. But an option nonetheless.

数据库存储是可扩展的,但出于临时易失性存储的目的,从数据库的角度来看可能不是最优雅的选择,因为它需要定期清理.就我个人而言,在我职业生涯的早期拥有扎实的数据库概念基础,这可能不会是许多开发人员可能会同意的;但从程序员的角度来看,为此目的使用数据库可能足以进行 Web 开发;然而,从 DAL 和 DB 开发的角​​度来看,这(对我而言)有可能要求额外的 DB 任务来实施高效的后端.

Database storage is scalable but for the intent purpose of temporary volatile storage is probably not the most elegant option from a database perspective as it would require periodical cleanup. Personally, having a strong foundation in database concepts earlier in my career this probably is not going to be something that many developers will likely agree with; but using the database for this purpose may suffice for Web Development from a programmers perspective; however from perspective of the DAL and DB development this (to me) has the potential for mandating an additional DB task to enforce an efficient backend.

Cookie 似乎是一个不错的选择,它结合了 Session 变量和缓存的理想"元素.

Cookies seem to be a nice option having the combined "desirable" elements of Session variables and caching.

=================================================

==================================================

基于答案;当事后需要持续持久性时,我认为 COOKIES 和 CACHING 似乎通常是全面的最佳实践建议,结合数据库存储;作为所呈现的可扩展性的潜在良好候选者.

Based on the answers; I think COOKIES and CACHING seem to be generally well rounded proposals for best practice across the board in combination with database storage when continued persistence is required after the fact; as potentially good candidates for scalability of the ones presented.

两者之间的最终选择似乎是基于需要存储的数据的数量和类型(例如敏感与非敏感以及是否担心客户端可能会更改其最终数据);除了对 COOKIES 的特殊考虑之外,它们可能会被客户端禁用.

The ultimate choice between the 2 would seem to be based on the amount and type of data requiring storage (e.g. sensitive vs non-sensitive and whether or not there is any concern that the client may alter the data on their end); in addition to special considerations for COOKIES in the fact that they may be disabled by the clients.

显然,根据所提供的答案明确指出并得出结论,但在可扩展性方面,没有一种万能解决方案;我可能错了,但这些似乎是可用的最佳选择.

Obviously, there is no one size fits all solution as clearly pointed out and concluded from the answers provided but in terms of scalability; I may be wrong but these seem to be the BEST choices available.

因为所有的反应都很好;我相当相信所有的帖子都是有用的,并且会接受 Erik 的答案作为一个全面的整体可扩展解决方案.我希望我可以选择多个已接受的答案,因为我相信 Tim 的回答也非常简洁明了.

Because all the responses are good; I'm fairly going to credit all the posts as useful and going to accept Erik's answer as a well rounded overall scalable solution. I wish I could select more than one accepted answer as I believe Tim's response was also very well layed out and concise.

Gupta 的回复也很好,但我想要对提议的答案进行更多详细说明,而不是重复以前的帖子.

Gupta's response was good also, but I wanted more elaboration of the proposed answer and not a repeat of previous posts.

谢谢各位!

推荐答案

在任何一大群人中,您永远不会对任何事情达成一致意见.这只是人的本性.部分原因源于 Dunning-Kruger 效应,该效应表明人们对某个主题的了解越少,他们就越有可能高估自己在该主题上的专业知识.换句话说,很多人认为他们知道某事,但只是因为他们不知道他们不知道.部分原因很简单,人们有不同的体验,有些人在 session 中没有发现问题,而有些人则在各种情况下都有,反之亦然......

You will never get unanimous opinion on anything in any large group of people. That's just human nature. Part of that stems from the Dunning-Kruger Effect which states that the less someone knows about a subject, the more likely they are to over value their expertise in that subject. In other words, lots of people think they know something, but only because they don't know they don't know it. Part of it is simply that people have different experiences, and some have found no problems with session, while others have in various situations, or vice versa...

因此,为了支持您的研究,这表明答案在很大程度上取决于要求,我们需要了解您的要求.如果这是一个高流量站点,并且在 Web 场中具有负载平衡的服务器,那么请尽可能远离会话.当然,可以在服务器场环境中以各种方式共享会话(会话服务器、分发缓存服务器等),但如果您能提供帮助,避免会话几乎总是更快.

So, to backup your research, which suggest that the answer depends heavily on the requirements, we need to understand what your requirements are. If this is to be a high traffic site, with load balanced servers in a web farm, then stay as far away from session as you can. Sure, it's possible to share session in various ways in a server farm environment (session server, distribute cache server, etc..), but avoiding session will almost always be faster if you can help it.

如果您的站点是单个服务器,并且不太可能超出此范围.并且您的流量模式相对较低,那么会话可能是一个有用的选择.但是,您应该始终意识到会话是不可靠的存储,并且可以随时消失.如果应用程序池被回收,会话就会消失.如果未捕获的异常冒泡到工作进程,则会话可能会消失.如果 IIS 认为没有足够的内存,则无论配置的任何超时值如何,您的会话都可能会消失.您也无法始终获得会话已结束的可靠通知,因为终止的会话不会触发 Session_End 事件.

If your site is a single server, and unlikely to ever grow beyond that. And your traffic patterns are relatively low, then session may be a useful option. However, you should always be aware that session is unreliable storage, and can disappear on you at any time. If the app pool is recycled, session is gone. If an uncaught exception bubbles up to the worker process, the session may be gone. If IIS thinks there's not enough memory, your session may be gone, regardless of any timeout values configured. You also can't always get reliable notification that a session has ended, since terminated sessions do not fire the Session_End event.

另一个问题是 Session 是序列化的.换句话说,IIS 防止多个线程一次写入会话,并且它通常通过在线程运行时锁定会话来实现这一点,如果它没有选择退出可写会话锁定.这在某些情况下会导致严重的问题,而在其他情况下只会导致性能不佳.如果您不打算在该方法中修改它,您可以通过使用只读会话属性标记各种方法来缓解这种情况.

Another issue is that Session is serialized. In other words, IIS prevents more than one thread from writing to the session at a time, and it often does this by locking the session while a thread is running if it has not opted out of writable session locking. This can cause severe problems in some cases, and merely poor performance in others. You can mitigate this by marking various methods with a read-only session attribute if you aren't going to be modifying it in that method.

最终,如果您确实选择使用会话,那么在可能的情况下尝试仅将其用于小而短暂的事情,如果不可能,则在会话丢失时以重新生成"数据的方式构建.例如,使用购物车中的商品数量示例,您可以编写一个方法,首先检查该值是否存在,如果不存在,则退出并从数据库中加载它.始终使用此方法访问变量,而不是直接从会话中访问它...这样,如果会话丢失,它只会重新加载它.

Ultimately, if you do choose to use session, then try to only use it for small, short lived things if at all possible, and if not possible then build in a way to "regenerate" the data if the session is lost. For instance, using your number of items in cart example, you could write a method that first checks to see if the value is there, and if not it goes out and loads it from the database. Always use this method to access the variable, rather than accessing it directly from session... this way, if the session is lost it will just reload it.

但是,话虽如此...对于购物车中的商品数量,我通常更喜欢使用 cookie 来获取此信息,因为无论如何 cookie 都会在每次加载时传递到页面,这是一个小的离散数据单位.对于您希望防止用户更改的敏感数据,通常更喜欢 Session.购物车中的商品数量根本不符合该规则.

However, having said this... For the number of items in a cart, I would generally prefer to use a cookie for this information, since cookies get passed to the page on every load anyways, and this is a small discrete unit of data. Generally prefer Session for sensitive data that you want to prevent the user from being able to change.. number of items in the cart simply doesn't fit that rule.

这篇关于MVC 中是否有最佳实践和推荐的 Session 变量替代方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆