我正在编写一个Web应用程序,允许用户浏览网站内的多个网页,提出某些请求.用户输入的所有信息都将存储在我创建的对象中.问题是我需要从网站的任何部分访问此对象,我真的不知道实现这一目标的最佳方法.我知道一个解决方案是使用会话变量,但我不知道如何在asp .net MVC中使用它们.我会在哪里声明会话变量?还有其他方法吗?
我认为你会想到事情是否真的属于会话状态.这是我发现自己经常做的事情,这是一个很好的强类型方法,但是在把事情放在会话上下文时你应该小心.不是所有东西都应该只是因为它属于某个用户.
在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对象,但无法弄清楚为什么我继续得到"实例未设置为Object错误的实例".我注意到在控制器中,当我尝试通过执行以下操作来访问会话时,我一直在收到该错误.这是因为this.HttpContext是Controller对象的一部分.
this.Session["blah"] // or this.HttpContext.Session["blah"]
但是,我想要的是HttpContext,它是System.Web命名空间的一部分,因为这是上面建议在Global.asax.cs中使用的答案.所以我必须明确地做以下事情:
System.Web.HttpContext.Current.Session["blah"]
这对我有所帮助,不确定我是否在这里做了一些不是MO的东西,但我希望它对某人有所帮助!
因为我不喜欢看到关于这个地方的"HTTPContext.Current.Session",所以我使用单例模式来访问会话变量,它为您提供了一个易于访问的强类型数据包.
[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}"] %>
这绝对不是访问会话变量的最佳方式,但它是直接路由.因此请谨慎使用(最好在快速原型制作过程中),并在适当时使用Wrapper/Container和OnSessionStart.
HTH
好吧,恕我直言..
永远不要在视图/母版页中引用会话
最小化Session的使用.MVC为此提供了TempData obj,它基本上是一个用于单次访问服务器的Session.
关于#1,我有一个强类型的主视图,它具有访问Session对象所代表的任何属性....在我的实例中,强大的主视图是通用的,这给了我一些关于强类型视图页面的灵活性
ViewMasterPageAdminViewModel { SomeImportantObjectThatWasInSession ImportantObject } AdminViewModel : AdminViewModel where TModel : class { TModel Content }
然后...
ViewPage>
虽然我不知道asp.net mvc,但这是我们应该在普通的.net网站上做的事情.它也适用于asp.net mvc.
YourSessionClass obj=Session["key"] as YourSessionClass; if(obj==null){ obj=new YourSessionClass(); Session["key"]=obj; }
您可以将其放在方法中以便于访问.HTH
有3种方法可以做到这一点.
你可以直接访问
HttpContext.Current.Session
你可以模拟
HttpContextBase
为.创建扩展方法
HttpContextBase
我更喜欢第三种方式.这个链接很好参考.
在BaseController中获取/设置HttpContext会话方法与Mocking HttpContextBase一起创建Get/Set方法
这些家伙给出了很好的答案,但我会提醒你不要总是依赖会议.这样做既快捷又容易,当然会起作用,但在所有的cicrumstances中都不会很好.
例如,如果您遇到托管不允许使用会话,或者您在Web场中或在共享SharePoint应用程序示例中的情况.
如果您想要一个不同的解决方案,您可以使用像Castle Windsor这样的IOC容器,创建一个提供程序类作为包装器,然后根据您的要求使用每个请求或会话生活方式保留一个类的实例.
IOC将确保每次返回相同的实例.
更复杂的是,如果您需要一个简单的解决方案,只需使用会话.
以下是一些感兴趣的实现示例.
使用此方法,您可以创建一个提供程序类:
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().UsingFactoryMethod( () => new CustomClassProvider(new CustomClass())).LifestylePerWebRequest()); }
我访问会话的方式是编写一个帮助程序类,其中封装了各种字段名称及其类型。我希望这个例子有帮助:
using System; using System.Collections.Generic; using System.Web; using System.Web.SessionState; namespace dmkp { ////// Encapsulates the session state /// 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; } } } }