Issue in deleting session ID from Dictionary object

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Manikrag
    New Member
    • Jun 2009
    • 62

    Issue in deleting session ID from Dictionary object

    Please help as this issue is driving us crazy...
    Any idea would be of great help..

    Application is running over IIS and I am getting error "
    Index was outside the bounds of the array." on the Session_Start on line
    Code:
    AllSessions[Session.SessionID] = GetSession.GetNewSession(Context);

    When I tried to catch the error I got random values for AllSessions.Cou nt. It touched 77 and after a day it came back on 66 and in an hour it touched 99.

    Now, my question is why I am getting error even after removing session from Dictionary object under Session_End event.

    Here is my global.asax file

    Code:
    <%@ Application Language="C#" %>
    <%@ Import Namespace="System.Collections.Generic" %>
    
    <script runat="server">
        
        private static Dictionary<String, GetSession> AllSessions = new Dictionary<String, GetSession>();
        
        void Application_Start(object sender, EventArgs e) 
        {
            Context.Cache.Insert("Web.AllSessions", AllSessions);
            // Code that runs on application startup
    
        }
        
        void Application_End(object sender, EventArgs e) 
        {
            //  Code that runs on application shutdown
    
        }
            
        void Application_Error(object sender, EventArgs e) 
        { 
            // Code that runs when an unhandled error occurs
    
        }
    
        void Session_Start(object sender, EventArgs e) 
        {
            try
    		{
    AllSessions[Session.SessionID] = GetSession.GetNewSession(Context);
            // Code that runs when a new session is started
    }
    catch (Exception ex)
    		{
    		Web.Globals.WriteError("SessionInCache.GetNewSessionForCache(Context) -> " + ex.Message +  "REMOTE_HOST: " + Context.Request.ServerVariables["REMOTE_HOST"] + " SessionID " + Context.Session.SessionID + " Number of sessions " + AllSessions.Count);
    		}
    
        }
    
        void Session_End(object sender, EventArgs e) 
        {
            // Code that runs when a session ends. 
            // Note: The Session_End event is raised only when the sessionstate mode
            // is set to InProc in the Web.config file. If session mode is set to StateServer 
            // or SQLServer, the event is not raised.
    
            AllSessions.Remove(Session.SessionID);
    
        }
           
    </script>
    here is my GetSession class

    Code:
    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    
    /// <summary>
    /// Summary description for GetSession
    /// </summary>
    public class GetSession
    {
        private String m_SessionId = null;
        public String m_UserAgent = null;
        public String m_RemoteHost = null;
        public String m_RemoteAddr = null;
        public String m_AcceptCharsets = null;
        public String m_AcceptEncodings = null;
        public String m_AcceptLanguage = null;
        public String m_EmplId = null;
        public String m_LoginName = null;
        public DateTime m_SessionStart = DateTime.UtcNow;
    
    	public GetSession()
    	{
    		//
    		// TODO: Add constructor logic here
    		//
    	}
        public static GetSession GetNewSession(HttpContext Context)
        {
            GetSession mySession = null;
            try
            {
                
    
                mySession = new GetSession();
                mySession = new GetSession();
                mySession.m_SessionId = Context.Session.SessionID;
                mySession.m_UserAgent = Context.Request.ServerVariables["HTTP_USER_AGENT"];
                mySession.m_RemoteHost = Context.Request.ServerVariables["REMOTE_HOST"];
    
                // Handle HTTP proxy forwarding
                if (Context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null) mySession.m_RemoteAddr = Context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                else if (Context.Request.ServerVariables["HTTP_FORWARDED"] != null) mySession.m_RemoteAddr = Context.Request.ServerVariables["HTTP_FORWARDED"];
                else mySession.m_RemoteAddr = Context.Request.ServerVariables["REMOTE_ADDR"];
    
                mySession.m_AcceptCharsets = Context.Request.ServerVariables["HTTP_ACCEPT_CHARSET"];
                mySession.m_AcceptEncodings = Context.Request.ServerVariables["HTTP_ACCEPT_ENCODING"];
                mySession.m_AcceptLanguage = Context.Request.ServerVariables["HTTP_ACCEPT_LANGUAGE"];
    
    
    
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
            }
            return mySession;
        }
    }
  • tlhintoq
    Recognized Expert Specialist
    • Mar 2008
    • 3532

    #2
    The error means... If you have an array of 10 items, and you try to access item number 15... The item number (the index) was outside of the bounds (the limits) of the array.

    You need to not just assume your values are good. For example if (value < maximum) then do your thing.

    I can make some general suggestions that apply to good coding practice.
    • Assume that everything is broken, or at least not ideal.
    • Presume that the user is going to provide data in a format or manner that you just didn't expect. If you use a textbox for a number, the user will type "One".
    • Assume that hardware breaks in the middle of what you are doing, so you have to recover.
    • Take a few extra lines of code to get standards like the boot drive, the number thousands seperator etc. Don't assume that you have a C: drive or that a comma is the separator because not everyone is in America.
    • Check that files/folders exist, even if you just did a call to make it: You may not have permissions.
    • Don't assume the harddrive has room for what you are doing: They do fill up. Usually right in the middle of you writing to your log file.
    • Get used to placing breakpoints and walking through the code line by line. Double check EVERYTHING on every line. Keep the "Locals" and "Autos" windows open so you can see your values.
      • Put a breakpoint on the first line of the method causing trouble.
      • When the code stops there, walk through line by line with F-10.
      • Check the values of your assumptions (looking at the Locals and Automatic variable windows as well as hovering the mouse over the variables in the code (hothelp will popup).
    • Stop. Breath. Relax. Then reason out the problem. Cut it down by sections or halves. "The value was good here, then at this method it wasn't. Where did it go between 'A' and 'B'?"
    • Range check and validate values. Confirm that you didn't get a zero when you are only set to accept 1-10. Confirm your objects and values aren't null. Initialize them to a known default if possible. If a selection can be from 0-10, then initialize to -1: Now you have something to check for.


    Example:
    Code:
    Graphics g = Graphics.FromImage(m_Undo);
    Presumes that m_Undo must be good (not null)(actually exists)(not in use)(you have permissions)(do esn't time out when accessed). If that assumption fails so does the program, because you can't make anything from a file if the file is null. Get used to validating data and assumptions in your code if you want it to be robust. For example:
    Code:
    if (m_Undo != null)
    {
       bool bSuccess = false;
       // Do your thing here, for example:
       if (myObject != null) bSuccess = true;
       // or
       if (denominator > 0) bSuccess = true;
       // or
       if (MyFunctionReturn != Failed) bSuccess = true;
       // Hurray, your thing worked!
    
       if (bSuccess)
       {
          // Then do this other thing if it worked
       }
       else
       {
          // Then do the failure recovery part / user failure message
       }
    
       return bSuccess; // If you want the calling method to know if it worked.
    }

    Comment

    Working...