ASP.NET MVC中的会话variables

我正在编写一个Web应用程序,允许用户浏览网站内的多个网页,提出某些请求。 用户input的所有信息都将存储在我创build的对象中。 问题是我需要从网站的任何部分访问这个对象,我不知道最好的方法来完成这一点。 我知道一个解决scheme是使用会话variables,但我不知道如何在asp.netnet MVC中使用它们。 我会在哪里声明一个会话variables? 有没有其他的方法?

如果事情真的属于会话状态,我想你会想一想。 这是我发现自己每时每刻都在做的事情,对于整个事情来说这是一个很好的强types方法,但是在将事情放入会话上下文时应该小心。 不是所有的东西都应该在那里,因为它属于某个用户。

在global.asax钩住OnSessionStart事件

void OnSessionStart(...) { HttpContext.Current.Session.Add("__MySessionObject", new MySessionObject()); } 

从HttpContext.Current属性!= null的代码中的任何位置,您都可以检索该对象。 我用扩展方法做这个。

 public static MySessionObject GetMySessionObject(this HttpContext current) { return current != null ? (MySessionObject)current.Session["__MySessionObject"] : null; } 

这样你可以在代码中

 void OnLoad(...) { var sessionObj = HttpContext.Current.GetMySessionObject(); // do something with 'sessionObj' } 

这里的答案是正确的,但我努力在ASP.NET MVC 3应用程序中实现它。 我想访问一个控制器中的Session对象,并不知​​道为什么我一直得到一个“实例没有设置为一个对象的错误的实例”。 我注意到,在一个控制器中,当我尝试通过执行以下操作来访问会话时,我一直在获取该错误。 这是由于this.HttpContext是Controller对象的一部分。

 this.Session["blah"] // or this.HttpContext.Session["blah"] 

但是,我想要的是System.Web命名空间的一部分的HttpContext,因为这是上面的答案在Global.asax.cs中使用的一个。 所以我不得不明确地做到以下几点:

 System.Web.HttpContext.Current.Session["blah"] 

这帮助了我,不知道我是否在这里做了任何不是M​​O的东西,但是我希望它能帮助别人!

因为我不喜欢看到“HTTPContext.Current.Session”这个地方,所以我使用单例模式来访问会话variables,它使您能够轻松访问强types的数据包。

 [Serializable] public sealed class SessionSingleton { #region Singleton private const string SESSION_SINGLETON_NAME = "Singleton_502E69E5-668B-E011-951F-00155DF26207"; private SessionSingleton() { } public static SessionSingleton Current { get { if ( HttpContext.Current.Session[SESSION_SINGLETON_NAME] == null ) { HttpContext.Current.Session[SESSION_SINGLETON_NAME] = new SessionSingleton(); } return HttpContext.Current.Session[SESSION_SINGLETON_NAME] as SessionSingleton; } } #endregion public string SessionVariable { get; set; } public string SessionVariable2 { get; set; } // ... 

那么你可以从任何地方访问你的数据:

 SessionSingleton.Current.SessionVariable = "Hello, World!"; 

如果您使用的是asp.net mvc,这是访问会话的一种简单方法。

从控制器:

 {Controller}.ControllerContext.HttpContext.Session["{name}"] 

从视图:

 <%=Session["{name}"] %> 

这绝对不是访问你的会话variables的最好方法,但它是一个直接的路线。 因此请谨慎使用(最好在快速原型开发过程中),并在适当时使用Wrapper / Container和OnSessionStart。

HTH

那么,恕我直言

  1. 永远不要在视图/母版页中引用会话
  2. 最大限度地减less会话的使用。 MVC为此提供了一个TempData对象,它基本上是一个存在于服务器之间的Session。

关于#1,我有一个强types的主视图有一个属性来访问任何会话对象代表….在我的实例中,强types的主视图是通用的,这给了我一些灵活性,关于强types的查看页面

 ViewMasterPage<AdminViewModel> AdminViewModel { SomeImportantObjectThatWasInSession ImportantObject } AdminViewModel<TModel> : AdminViewModel where TModel : class { TModel Content } 

接着…

 ViewPage<AdminViewModel<U>> 

虽然我不知道关于asp.net mvc,但这是我们应该在一个正常的.net网站上做的。 它也应该为asp.net mvc工作。

 YourSessionClass obj=Session["key"] as YourSessionClass; if(obj==null){ obj=new YourSessionClass(); Session["key"]=obj; } 

你会把它放在一个方便访问的方法。 HTH

从家伙的伟大答案,但我会告诫你不要总是依靠会议。 这样做是快速和容易的,当然会起作用,但在所有的情况下都不会很好。

例如,如果遇到托pipe不允许使用会话的场景,或者在Web场中,或者在共享SharePoint应用程序的示例中。

如果您想要一个不同的解决scheme,您可以使用IOC容器 (如Castle Windsor )创build提供者类作为包装,然后根据您的要求使用每个请求或会话生活方式保留一个类的实例。

国际奥委会将确保每次都返回相同的实例。

更复杂的是,如果你需要一个简单的解决scheme,只需使用会话。

以下是一些有趣的实现示例。

使用这种方法,您可以创build一个提供者类:

 public class CustomClassProvider : ICustomClassProvider { public CustomClassProvider(CustomClass customClass) { CustomClass = customClass; } public string CustomClass { get; private set; } } 

并注册它像这样:

 public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register( Component.For<ICustomClassProvider>().UsingFactoryMethod( () => new CustomClassProvider(new CustomClass())).LifestylePerWebRequest()); } 

有3种方法可以做到这一点。

  1. 你可以直接访问HttpContext.Current.Session

  2. 你可以模拟HttpContextBase

  3. HttpContextBase创build一个扩展方法

我更喜欢第三种方式。这个链接是很好的参考。

在BaseController中获取/设置HttpContext会话方法vs模拟HttpContextBase来创buildGet / Set方法

您可以使用ViewModelBase作为所有模型的基类,这个类将负责从会话中提取数据

 class ViewModelBase { public User CurrentUser { get { return System.Web.HttpContext.Current.Session["user"] as User }; set { System.Web.HttpContext.Current.Session["user"]=value; } } } 

你可以在HttpContextBase上写一个扩展方法来处理会话数据

 T FromSession<T>(this HttpContextBase context ,string key,Action<T> getFromSource=null) { if(context.Session[key]!=null) { return (T) context.Session[key]; } else if(getFromSource!=null) { var value = getFromSource(); context.Session[key]=value; return value; } else return null; } 

在控制器中使用下面的内容

 User userData = HttpContext.FromSession<User>("userdata",()=> { return user object from service/db }); 

第二个参数是可选的,当会话中不存在值时,将使用该键填充会话数据。

我访问会话的方式是编写一个帮助类,封装各种字段名称及其types。 我希望这个例子有助于:

 using System; using System.Collections.Generic; using System.Web; using System.Web.SessionState; namespace dmkp { /// <summary> /// Encapsulates the session state /// </summary> public sealed class LoginInfo { private HttpSessionState _session; public LoginInfo(HttpSessionState session) { this._session = session; } public string Username { get { return (this._session["Username"] ?? string.Empty).ToString(); } set { this._session["Username"] = value; } } public string FullName { get { return (this._session["FullName"] ?? string.Empty).ToString(); } set { this._session["FullName"] = value; } } public int ID { get { return Convert.ToInt32((this._session["UID"] ?? -1)); } set { this._session["UID"] = value; } } public UserAccess AccessLevel { get { return (UserAccess)(this._session["AccessLevel"]); } set { this._session["AccessLevel"] = value; } } } }