簡體   English   中英

為什么會話對象拋出空引用異常?

[英]Why does session object throw a null reference 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中

  <system.web>
      <sessionState timeout="40" />
  </system.web>

只要客戶端不清除它,並且Web服務器啟動並運行,您的會話將持續40分鍾。

訪問Session對象時始終檢查null!
您可以編寫一些可用於此的小實用程序:

public class SessionData
{
    public static T Get<T>(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處理程序)發出請求。 它對於長時間打開的頁面非常有用,例如巨大的編輯表單。
另外,請注意,調試和發布配置有不同的會話超時值!

首先,您可以使用這樣的代碼

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不為null,請重新檢查它是否具有"YourAssessment""MyAssessment"

當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);


}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM