为什么会话对象抛出空引用exception?

在我的一些aspx页面上,我正在检查这样的会话

if (bool.Parse(Session["YourAssessment"].ToString()) == false && bool.Parse(Session["MyAssessment"].ToString()) == true) { Response.Redirect("~/myAssessment.aspx"); } 

如果我经常继续播放页面,它工作正常,但如果我至少在5分钟内没有对页面做任何事情,那么运行页面会抛出错误

 Object reference not set to an instance of an object. 

以下是此堆栈

 [NullReferenceException: Object reference not set to an instance of an object.] yourAssessment.Page_Load(Object sender, EventArgs e) in d:\Projects\NexLev\yourAssessment.aspx.cs:27 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35 System.Web.UI.Control.OnLoad(EventArgs e) +91 System.Web.UI.Control.LoadRecursive() +74 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2207 

有些人能解释我这种奇怪的行为吗?

正如我们所知,默认情况下会话持续时间为20分钟。

EDITED

看到我有一个页面默认的aspx,它有一个按钮修复了一些基础上的重定向在默认页面它检查像这样

 protected void Page_Load(object sender, EventArgs e) { if (!HttpContext.Current.Request.IsAuthenticated) { Response.Redirect("~/login.aspx"); } else { Session["YourAssessment"] = false; Session["MyAssessment"] = false; } } 

按钮点击它有

 protected void imgClientFreeEval_Click(object sender, System.Web.UI.ImageClickEventArgs e) { if (HttpContext.Current.Request.IsAuthenticated) { string sqlQuery = "SELECT count(*) FROM SurveyClient WHERE UserID='" + cWebUtil.GetCurrentUserID().ToString() + "'"; SqlParameter[] arrParams = new SqlParameter[0]; int countSurvey = int.Parse( Data.GetSQLScalerVarQueryResults(sqlQuery).ToString()); if (countSurvey > 0) { Session["YourAssessment"] = true; Session["MyAssessment"] = false; } Response.Redirect((countSurvey > 0) ? "~/yourAssessment.aspx" : "~/myAssessment.aspx"); } else { Response.Redirect("~/login.aspx"); } 

在myAssessment页面上,它会像这样检查

 protected void Page_Load(object sender, EventArgs e) { if (!HttpContext.Current.Request.IsAuthenticated) { Response.Redirect("~/login.aspx"); } else { if (Session["YourAssessment"] != null && Session["MyAssessment"] != null && bool.Parse(Session["YourAssessment"].ToString()) && !bool.Parse(Session["myAssessment"].ToString())) { Response.Redirect("~/yourAssessment.aspx"); } } } 

在你的assessmtn上,它会像这样检查

 protected void Page_Load(object sender, EventArgs e) { if (!HttpContext.Current.Request.IsAuthenticated) { Response.Redirect("~/login.aspx"); } else { if (Session["YourAssessment"] != null && Session["MyAssessment"] != null && !bool.Parse(Session["YourAssessment"].ToString()) && bool.Parse(Session["MyAssessment"].ToString())) { Response.Redirect("~/myAssessment.aspx"); } PopulateAllSurveyByUser(); if (ViewState["surveyClientID"] != null) { grdSurveyDetail.Visible = true; PopulateSurveyDetails( int.Parse(ViewState["surveyClientID"].ToString())); } else { grdSurveyDetail.Visible = false; } } } 

有什么问题请解释一下?

首先需要检查该会话变量是否存在

 if(Session["YourAssessment"] != null) // Do something with it else // trying to call Session["YourAssessment"].ToString() here will FAIL. 

发生这种情况,因为您的会话具有生命周期,这意味着 – 它过期(定义它的cookie过期) – 因此您的对象消失。 您可以在web.config中增加sessionState timeout ,以使会话持续更长时间。

例如,在web.config中

     

只要客户端不清除它,并且Web服务器启动并运行,您的会话将持续40分钟。

访问Session对象时始终检查null!
您可以编写一些可用于此的小实用程序:

 public class SessionData { public static T Get(string key) { object value = HttpContext.Current.Session[key]; if(value == null) return default(T); try { return (T)value; } catch(Exception e) { return default(T); } } public static void Put(string key, object value) { HttpContext.Current.Session[key] = value; } } 

如果应用程序池被回收,则会话可以为null。 出现这种情况的原因很多……

保持服务器不会丢失会话的一个技巧是从javascript向服务器“ping”。 它可以每隔一分钟向一些虚拟URL(空页,或者如果你是一个伪装,对.ashx处理程序)发出请求。 它对于您长时间保持打开的页面非常有用,例如巨大的编辑表单。
另外,请注意,调试和发布配置有不同的会话超时值!

如果Session不为null,请重新检查它是否具有"YourAssessment""MyAssessment"

首先,您可以使用这样的代码

 if (!bool.Parse(Session["YourAssessment"].ToString()) && bool.Parse(Session["MyAssessment"].ToString())) Response.Redirect("~/myAssessment.aspx"); 

您确定Sessions不为null

像这样检查

 if (Session["YourAssessment"] != null && Session["MyAssessment"] != null && !bool.Parse(Session["YourAssessment"].ToString()) && bool.Parse(Session["MyAssessment"].ToString())) Response.Redirect("~/myAssessment.aspx"); 

当Session到期时,您在会话中放置的对象(如Session [“YourAssessment”])将变为null,并且对这些对象的.toString()方法调用将引发Object引用错误。 要解决此问题,必须首先检查以确保在尝试执行toString()之前会话变量为null。

  if(Session["YourAssessment"] != null){ if (bool.Parse(Session["YourAssessment"].ToString()) == false && bool.Parse(Session["MyAssessment"].ToString()) == true) { Response.Redirect("~/myAssessment.aspx"); } } 

而不是.ToString和Boolean.Parse做Convert.ToBoolean(Session["YourAssessment"])

当我尝试Boolean b = Convert.ToBoolean(null) b = false;)

好了所有关于这一点的文章,似乎问题是IIS应用程序重新启动,如果你的会话存储在可以删除会话变量的会话中。 因此,尝试记录应用程序结束事件并查看是否是这种情况,将其放入Global.asax.cs application_end事件中,此代码将记录应用程序重新启动及其发生的原因:

 protected void Application_End(object sender, EventArgs e) { HttpRuntime runtime = (HttpRuntime)typeof(System.Web.HttpRuntime).InvokeMember("_theRuntime", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField, null, null, null); string shutDownMessage = ""; if (runtime != null) { shutDownMessage = Environment.NewLine + "Shutdown: " + (string)runtime.GetType().InvokeMember("_shutDownMessage", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, null, runtime, null) + Environment.NewLine + "Stack: " + Environment.NewLine + (string)runtime.GetType().InvokeMember("_shutDownStack", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, null, runtime, null); } string logFile = HttpContext.Current.Server.MapPath(~/AppEndLog.log"); string logMsg = ""; if (File.Exists(logFile)) logMsg = logMsg + File.ReadAllText(logFile) + Environment.NewLine + Environment.NewLine; logMsg = logMsg + Environment.NewLine + "ApplicationEnd - " + DateTime.Now.ToString() + shutDownMessage; File.WriteAllText(logFile, logMsg); }