asp.net-mvc ASP.NET MVC 会话 vs 全局 vs 缓存
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/915470/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ASP.NET MVC Session vs Global vs Cache
提问by John Gietzen
I have an application that was written in vanilla ASP.NET that I would like to port over to ASP.NET MVC.
我有一个用普通 ASP.NET 编写的应用程序,我想将其移植到 ASP.NET MVC。
I, however, am confused about the right place to persist objects. I need to persist for a couple reasons:
然而,我对持久化对象的正确位置感到困惑。我需要坚持几个原因:
- I would like all to have a singledatabase connection, wrapped in a "repository" or "manager" style object.
- Each user has a user object that needs to be saved on a per-session basis.
- 我希望所有人都有一个单独的数据库连接,包装在“存储库”或“管理器”样式对象中。
- 每个用户都有一个用户对象,需要在每个会话的基础上进行保存。
Normally, I would say that #1 would be saved as a static item in the Globals.asax that can be hit using Global.Repositoryor similar.
通常,我会说 #1 将被保存为 Globals.asax 中的静态项目,可以使用Global.Repository或类似的方法进行命中。
And I would normally say that #2 should be a property with a session backing store somewhere in the base class of the pages.
我通常会说#2 应该是一个属性,在页面的基类中的某个地方有一个会话后备存储。
Now the reason I am confused is that I have heard that sessions have changed in MVC, and the Global.asax no longer holds the same class. Also, the concept of pages has been removed, so adding a property to the base class of a controller seems... wrong.
现在我感到困惑的原因是我听说 MVC 中的会话发生了变化,并且 Global.asax 不再拥有相同的类。此外,页面的概念已被删除,因此向控制器的基类添加属性似乎......错误。
What say yall?
yall 怎么说?
回答by
Your database would go in a base class for your controllers. This base class should extend Controller, and all your controllers should extend the base class. Here's a little example:
您的数据库将进入控制器的基类。这个基类应该扩展 Controller,你的所有控制器都应该扩展基类。这是一个小例子:
public class BaseController : Controller
{
private AuthServices _auth;
private LogHelper _log;
private Repository _repository;
/// <summary>
/// <see cref="AuthServices"/>
/// </summary>
protected AuthServices Authorization
{
get { return _auth ?? (_auth = new AuthServices()); }
}
/// <summary>
/// <see cref="LogHelper"/>
/// </summary>
protected LogHelper Log
{
get { return _log ?? (_log = new LogHelper()); }
}
/// <summary>
/// <see cref="Repository"/>
/// </summary>
protected Repository Repository
{
get { return _repository ?? (_repository = new Repository()); }
}
}
Notice the lazy instantiation. That allows me to sneak in before running tests and set my private fields with mocks.
注意惰性实例化。这允许我在运行测试之前潜入并使用模拟设置我的私有字段。
As for the session, your User object can still be saved in the session just as in a traditional ASP.NET application. Almost everything is still around (Response, Cache, Session, etc), but some of them have been wrapped with classes from System.Web.Abstractions so that they can be mocked for testing. They all still behave the same way, though you shouldn't use some of them in their traditional role (e.g., don't Response.Redirect, return an ActionResult such as RedirectToRouteResult that performs your redirection).
至于会话,您的 User 对象仍然可以像在传统的 ASP.NET 应用程序中一样保存在会话中。几乎所有东西都还在(响应、缓存、会话等),但其中一些已经用 System.Web.Abstractions 中的类包装,以便可以模拟它们进行测试。它们的行为方式仍然相同,但您不应该在它们的传统角色中使用其中的一些(例如,不要使用 Response.Redirect,返回一个 ActionResult,例如执行重定向的 RedirectToRouteResult)。
As for the reasoning behind your questions....
至于你的问题背后的原因......
Don't stress on a single db connection. Depending on your implementation it may even be a bad idea, as requests may step on each other. Just open your connex, use it, and dispose/close it when done.
不要强调单个数据库连接。根据您的实现,这甚至可能是一个坏主意,因为请求可能会相互影响。只需打开您的连接器,使用它,并在完成后处理/关闭它。
Also, one of the biggest changes that MVC brings is the rejection of the stateful model that traditional ASP.NET attempted to bring to web development. All that framework and viewstate doesn't exist anymore (pay no attention to the man behind the curtain). The less state you hold onto the less complex and more robust your web application is. Try it, you might like it.
此外,MVC 带来的最大变化之一是拒绝了传统 ASP.NET 试图为 Web 开发带来的有状态模型。所有的框架和视图状态都不再存在(不要注意窗帘后面的那个人)。您持有的状态越少,您的 Web 应用程序就越复杂、越健壮。试试吧,你可能会喜欢。
回答by Tony Borf
If you use sessions I would recommend having a session class, so that you only need to specify the string name once in code and this will give you IntelliSence also.
如果您使用会话,我建议您使用会话类,这样您只需在代码中指定一次字符串名称,这也将为您提供 IntelliSence。
public static class SessionHandler
{
// User Values
private static string _userID = "UserID";
private static string _userRole = "UserRole";
public static string UserID
{
get
{
if (HttpContext.Current.Session[SessionHandler._userID] == null)
{ return string.Empty; }
else
{ return HttpContext.Current.Session[SessionHandler._userID].ToString(); }
}
set
{ HttpContext.Current.Session[SessionHandler._userID] = value; }
}
public static string UserRole
{
get
{
if (HttpContext.Current.Session[SessionHandler._userRole] == null)
{ return string.Empty; }
else
{ return HttpContext.Current.Session[SessionHandler._userRole].ToString(); }
}
set
{ HttpContext.Current.Session[SessionHandler._userRole] = value; }
}
}
回答by Craig Stuntz
Sessions haven't changed at all in MVC. The GlobalApplication class in Global.asax still exists, too. Pages exist, also, that you would want to refer to a repository in a controller rather than a page. Adding a property to a base controller class is fine; I do it all the time.
MVC 中的会话根本没有改变。Global.asax 中的 GlobalApplication 类也仍然存在。页面也存在,您希望引用控制器中的存储库而不是页面。向基本控制器类添加属性很好;我总是这样做。
回答by Steve
You can create a model binder to encapsulate state.
您可以创建模型绑定器来封装状态。
(See Steve Sanderson's mvc book on his shopping cart implementation)
(参见史蒂夫桑德森关于他的购物车实现的 mvc 书)
With the model binder, you have access to the controllerContext - which has the HttpContext.
使用模型绑定器,您可以访问具有 HttpContext 的 controllerContext。

