locked
losing session values RRS feed

  • Question

  • User227128234 posted
    Hi all,
    I'm developing a web site using VS2005 and C#. I have used session variables in all web forms along the project and they work OK, but I'm having problems specially in a web form. After finishing a function in that web form, all session values are lost (the timeout is set to 60 minutes, so the problem is not timeout). It is quite strange.... anyone had the same problem before?? Session values dissapeared suddenly??? Is there another way to store values rather than session variables??? (I'd like to store only a login).

    Thanks in advance,
    Javier.

    Saturday, June 10, 2006 12:43 PM

All replies

  • User2032526919 posted

    Hi,

    which session mode do you use? InProc, StateServer or SQLServer? (You can check that in web.config  on <sessionState> element). And what function are you finishing on thr form, does it modify folders or files within the site?

    Saturday, June 10, 2006 1:56 PM
  • User227128234 posted
    Thanks Teemu,

    What I have in my web.config file is as follows:

    <sessionState
          cookieless="false"
          timeout="60" />

    And yes, inside that function I delete some files and directories... Because you asked about it, I suppose that the problem might be there.... when deleting files and directories. How can I fix that??? The files and directories that I delete are within the site, I mean, in subfolders of web site folder.

    Thanks again,
    Javier.

    Saturday, June 10, 2006 2:08 PM
  • User2032526919 posted

    Hi,

    default mode is InProc when session data is stored in-process with the application.When AppDomain (basically your application) restarts due to a change in web.config, new dlls, or changes in content directories, you lose session values. See this: http://blogs.msdn.com/toddca/archive/2005/12/01/499144.aspx

    E.g you cause AppDomain restarts when working with the directories. You can't avoid restarts any other way than provided in the post, but you can prevent losing sessions by using either StateServer or SQLServer as session store.

    Saturday, June 10, 2006 2:16 PM
  • User227128234 posted
    Thanks very much Teemu,
    I've tried what you said but it doesn't work.
    Now my web.config file has the following lines:

     <sessionState
          mode="StateServer"
          stateConnectionString="tcpip=localhost:42424" 
          cookieless="false"
          timeout="60" />

    And when I try to execute my website, the following error comes up:

    System.Web.HttpException: Unable to make the session state request to the session state server. Please ensure that the ASP.NET State service is started and that the client and server ports are the same.  If the server is on a remote machine, please ensure that it accepts remote requests by checking the value of HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\AllowRemoteConnection.  If the server is on the local machine, and if the before mentioned registry value does not exist or is set to 0, then the state server connection string must use either 'localhost' or '127.0.0.1' as the server name.

    I've checked the registry value as the error says and AllowRemoteConnection is set to 1 (my application must support remote connections) and the default port is set to 42424. I suppose this port refers to server side, but what about client side??? The error says that ports must be the same. Where can I change client port? What do I have to do???

    Thanks again. Your help would be great coz I have to hand this project next week :-(
    Cheers,
    Javier.

    Sunday, June 11, 2006 4:19 AM
  • User2032526919 posted

    Did you also just check that the ASP.NET state service is also on? (on Services on the server). The port ASP.NET tries to use when connecting to the state service is specified in stateConnectionString. And note that you need to give the IP address in stateConnectionString, case you want ASP.NET to access state service remotely (if state server is on separate machine).

    Here's something on the subject
    http://www.awprofessional.com/articles/article.asp?p=31842&seqNum=3&rl=1

    Also run search on Google with http://www.google.com/search?hl=en&q=allowremoteconnection+%22asp.net+state+service%22

     

     

    Sunday, June 11, 2006 4:39 AM
  • User227128234 posted
    Thanks again Teemu,
    Yes, this service is working, but now I get an error related to serialization.
    The first session variable I use is:
    Session["client"]=us;

    where us is an instance of User class. The class has before the definition (public class User)  [Serializable] key, but still doesn`t work. I got the following error:

    Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode.

    And, as I said, the object I want to store in the Session variable belongs to a class that is serializable.

    Any tip?? Thanks again. Hope this will be done shortly...
    Javier


    Sunday, June 11, 2006 4:49 AM
  • User2032526919 posted

    Does User class have members which wouldn't be serializable? If it has, then they are the issue.

     It's not enough to set User class with Serializable attribute, in case it's members can't be serialized (such as database connection etc which for obvious reasons isn't serializable). Object to be serializable, it's members should also be serializable or explicltty set to be non-serializable (with NonSerialized attribute)

    Sunday, June 11, 2006 5:02 AM
  • User227128234 posted
    Thanks Teemu,

    All private attributes in that class are strings, booleans or ArrayLists....it is true that in some function inside that class I use a DB connection, but that connection is declared locally in that function. So, I suppose all members in that class are serializable and with [Serializable()] key before class definition should be enough, but it doesn't work...or Do I have to say something inside that functions that use a database connection???.... :-(. This thing is driving me crazy....

    Any other tip please???
    Thanks again.

    Sunday, June 11, 2006 5:35 AM
  • User2032526919 posted

    If you don't have that as a member variable on your class, it shouldn't then matter. Note that it concerns all properties, member variables etc, not methods. Also if you have ArrayList, you need to take care that objects contained by it are also serializable.

    If that doesn't help can you post the outline of your User class?

    Sunday, June 11, 2006 6:48 AM
  • User227128234 posted
    Thanks Teemu,
    I've checked the attributes and all of them are serializable, so, I don't know what the error might be... Here you are User class (sorry, it is quite long, but not sure what is important...). Hope this helps to fix the problem.
    Thanks again,
    Javier.


    /// <summary>
    /// User class
    /// </summary>
    ///
    [Serializable()]
    public class User
    {

        /// <summary>
        /// Constructor 1: Build an empty instance (all attributes equal to null) of User class
        /// </summary>

        public User()
        {
            login = null;
            name = null;
            surname = null;
            password = null;
            email = null;
            lastAccess = null;
            role = null;
            motionActivated = false;
            cam = new Camera();
            motionEpisodes = new ArrayList();
            livImage = new liveImage();
          
        }
       
        /// <summary>
        /// Constructor 2: Build an instance of User class given the parameters
        /// </summary>
        /// <param name="loginU">user's login</param>
        /// <param name="nameU">user's name</param>
        /// <param name="surnameU">user's surname</param>
        /// <param name="passwordU">user's password</param>
        /// <param name="emailU">user's e-mail</param>
        /// <param name="lastAccessU">user's last Access to the system</param>
        /// <param name="roleU">user's role: administrator or client</param>
        /// <param name="motionActivatedU">user's motion activated: yes/no</param>

        public User(String loginU, String nameU, String surnameU, String passwordU, String emailU, String lastAccessU, String roleU,Boolean motionActivatedU)
        {
            login = loginU;
            name = nameU;
            surname = surnameU;
            password = passwordU;
            email = emailU;
            lastAccess = lastAccessU;
            role = roleU;
            motionActivated = motionActivatedU;
            cam = new Camera();
            motionEpisodes = new ArrayList();
            livImage = new liveImage();
           
        }

        /// <summary>
        /// Get user's login
        /// </summary>
        /// <returns>user's login</returns>

        public String getLogin()
        {
            return login;
        }

        /// <summary>
        /// Get user's name
        /// </summary>
        /// <returns>user's name</returns>

        public String getName()
        {
            return name;
        }

        /// <summary>
        /// Get user's surname
        /// </summary>
        /// <returns>user's surname</returns>
     
        public String getSurname()
        {
            return surname;
        }

        /// <summary>
        /// Get user's password
        /// </summary>
        /// <returns>user's password</returns>

        public String getPassword()
        {
            return password;
        }

        /// <summary>
        /// Get user's e-mail
        /// </summary>
        /// <returns>user's e-mail</returns>

        public String getEmail()
        {
            return email;
        }

        /// <summary>
        /// Get user's role
        /// </summary>
        /// <returns>user's role</returns>
     
        public String getRole()
        {
            return role;
        }

        /// <summary>
        /// Get user's motion activated attribute
        /// </summary>
        /// <returns>user's motion activated attribute</returns>

        public Boolean getMotion()
        {
            return motionActivated;
        }

        /// <summary>
        /// Get camera object that is being used by current user
        /// </summary>
        /// <returns>camera object</returns>

        public Camera getCamera()
        {
            return cam;
        }

        /// <summary>
        /// Check if the user is registered in the system
        /// </summary>
        /// <param name="loginU">user's login</param>
        /// <param name="passwordU">user's password</param>


        public void logInUser(String loginU, String passwordU)
        {
            // Retrieve the information from database
            fetchUser(loginU, passwordU);
            if (login != null) // The user exists in the system
                registerConnectedUser(); // The user is connected to the system.
        }

        /// <summary>
        /// Retrieve User information from the DataBase
        /// </summary>
        /// <param name="loginU">user's login</param>
        /// <param name="passwordU">user's password</param>
      
        private void fetchUser(String loginU, String passwordU)
        {
      
           
            SqlDataReader reader;
            // Get DB parameters from web.config file
            string serverIP = WebConfigurationManager.AppSettings["serverIP"];
            string TCPPort = WebConfigurationManager.AppSettings["TCPPort"];
            string DBName = WebConfigurationManager.AppSettings["DBName"];
            string DBLogin = WebConfigurationManager.AppSettings["DBLogin"];
            string DBPassword = WebConfigurationManager.AppSettings["DBPassword"];


            // New DBConnection instance
           
            DBConnection connection = new DBConnection(serverIP, TCPPort, DBName, DBLogin, DBPassword);

            // To set the SQL query: select all user data given the name and login introduced
            connection.setQueryToCommand("SELECT * FROM USERM WHERE login='" + loginU + "' AND password='" + encryptSHA1(passwordU) + "';");

            // Get reader
            reader = connection.getReader();
            reader.Read();

            if (reader.HasRows == true) // The user exists. Fill object attributes    
            {
                login = reader[0].ToString();
                name = reader[1].ToString();
                surname = reader[2].ToString();
                password = reader[3].ToString();
                email = reader[4].ToString();
                lastAccess = reader[5].ToString();
                role = reader[6].ToString();
                if (reader[7].ToString().Equals("yes"))
                    motionActivated = true;
                else
                    motionActivated = false;
            }

            reader.Close();

            if (connection != null)
                if (connection.getConnection().State == ConnectionState.Open)
                    connection.closeConnection();
        }


        /// <summary>
        /// Register connected user in the system
        /// </summary>

        private void registerConnectedUser()
        {
            updateUser(DateTime.Now);
        }

        /// <summary>
        /// Register connected user in the DB: update lastAccess
        /// </summary>
        /// <param name="currentTime"></param>

        private void updateUser(DateTime currentTime)
        {       
            DataRow[] foundRow;
            // Get DB parameters from web.config file
            string serverIP = WebConfigurationManager.AppSettings["serverIP"];
            string TCPPort = WebConfigurationManager.AppSettings["TCPPort"];
            string DBName = WebConfigurationManager.AppSettings["DBName"];
            string DBLogin = WebConfigurationManager.AppSettings["DBLogin"];
            string DBPassword = WebConfigurationManager.AppSettings["DBPassword"];

            // New ADO.NET database instance. This object manages with ACTIVE_USERS table
            ADODBConnection connection = new ADODBConnection(serverIP, TCPPort,DBName,DBLogin, DBPassword, "SELECT * from ACTIVE_USERS;");

            // Found rows whose login is current user in ACTIVE_USERS table
            foundRow = connection.getDataTable().Select("login='" + login + "'");

            if (foundRow.Length == 1) // The user exists in ACTIVE_USERS table already          
                connection.updateRow(login,currentTime.ToString()); // Update user
            else // Insert new register in ACTIVE_USERS
                connection.addNewRow(login,currentTime.ToString());

            // New DBConnection instance       
            DBConnection connection2 = new DBConnection(serverIP, TCPPort, DBName, DBLogin, DBPassword);

            // To set the SQL query: update lastAccess attribute in USERM table for current user
            connection2.setQueryToCommand("UPDATE USERM set lastAccess='" + currentTime + "' WHERE login='" +login +"';");
            connection2.executeSqlSentence();

            if (connection2 != null)
                if (connection2.getConnection().State == ConnectionState.Open)
                    connection2.closeConnection();

            // Update lastAccess attribute in current object
            lastAccess = currentTime.ToString();

        }  


        /// <summary>
        /// Encrypt a string using SHA1 hash algorithm
        /// </summary>
        /// <param name="vsValue">string to encrypt</param>
        /// <returns>encrypted string</returns>
        ///

        private string encryptSHA1(string vsValue)
        {
            HashAlgorithm hashValue = new SHA1CryptoServiceProvider();

            // Convert the original string to array of Bytes
            byte[] byteValue = Encoding.UTF8.GetBytes(vsValue);

            Decoder dec = Encoding.UTF8.GetDecoder();

            // Compute the Hash, returns an array of Bytes
            byte[] byteHash = hashValue.ComputeHash(byteValue);

            hashValue.Clear();

            // Return a base 64 encoded string of the Hash value
            return (Convert.ToBase64String(byteHash));
        }

        /// <summary>
        /// Set camera object values in current user instance
        /// </summary>

        public void viewCameraConfiguration()
        {     
            // Get camera object from camera class
            cam.getCameraConfiguration();
        }
     
              

        /// <summary>
        /// Change personal details. In this case, password is also changed
        /// </summary>
        /// <param name="newName">new user's name</param>
        /// <param name="newSurname">new user's surname</param>
        /// <param name="newEmail">new user's e-mail</param>
        /// <param name="newPassword">new user's password</param>
        /// <param name="motionActivatedU">new user's motion activated value</param>   

        public void changePersonalDetails(string newName, string newSurname, string newEmail, string newPassword,Boolean motionActivatedU)
        {
          //Update new personal details on DB
            updateUser(newName, newSurname, newEmail, newPassword, motionActivatedU);       
        }

        /// <summary>
        /// Update new personal details on DB. Password has been changed
        /// </summary>
        /// <param name="newName">new user's name</param>
        /// <param name="newSurname">new user's surname</param>
        /// <param name="newEmail">new user's e-mail</param>
        /// <param name="newPassword">new user's password</param>
        /// <param name="motionActivatedU">new user's motion activated value</param>  

        private void updateUser(string newName, string newSurname, string newEmail, string newPassword, Boolean motionActivatedU)
        {                      
            string motionActivatedString = "no";
            // Get DB parameters from web.config file
            string serverIP = WebConfigurationManager.AppSettings["serverIP"];
            string TCPPort = WebConfigurationManager.AppSettings["TCPPort"];
            string DBName = WebConfigurationManager.AppSettings["DBName"];
            string DBLogin = WebConfigurationManager.AppSettings["DBLogin"];
            string DBPassword = WebConfigurationManager.AppSettings["DBPassword"];


            string encryptedNewPassword = encryptSHA1(newPassword);
            // New DBConnection instance       
            DBConnection connection = new DBConnection(serverIP, TCPPort, DBName, DBLogin, DBPassword);

            if (motionActivatedU)
                motionActivatedString = "yes";

            // To set the SQL sentence:update motionActivated attribute in ACTIVE_USERS table
            connection.setQueryToCommand("UPDATE ACTIVE_USERS set motionActivated='" + motionActivatedString + "'WHERE login='" + login + "';");

            connection.executeSqlSentence();

            // To set the SQL sentence:update name,surname,password and email address given the login in USERM table
            connection.setQueryToCommand("UPDATE USERM set name='" + newName + "',surname='" + newSurname + "',email='" + newEmail + "',password='" + encryptedNewPassword + "',motionActivated='" + motionActivatedString + "'WHERE login='" + login + "';");

            connection.executeSqlSentence();

            // To update user object
            name = newName;
            surname = newSurname;
            email = newEmail;
            password = encryptedNewPassword;
            motionActivated = motionActivatedU;
          
            if (connection != null)
                if (connection.getConnection().State == ConnectionState.Open)
                    connection.closeConnection();      
        }


        /// <summary>
        /// Change personal details. In this case, password is not changed
        /// </summary>
        /// <param name="newName">new user's name</param>
        /// <param name="newSurname">new user's surname</param>
        /// <param name="newEmail">new user's e-mail</param>   
        /// <param name="motionActivatedU">new user's motion activated value</param>    

        public void changePersonalDetails(string newName, string newSurname, string newEmail,Boolean motionActivatedU)
        {
            //Update new data on DB
            updateUser(newName, newSurname, newEmail,motionActivatedU);

        }

        /// <summary>
        /// Update new personal details on DB. Password is not changed
        /// </summary>
        /// <param name="newName">new user's name</param>
        /// <param name="newSurname">new user's surname</param>
        /// <param name="newEmail">new user's e-mail</param>  
        /// <param name="motionActivatedU">new user's motion activated value</param>  
     
        private void updateUser(string newName, string newSurname, string newEmail, Boolean motionActivatedU)
        {
            string motionActivatedString = "no";
            // Get DB parameters from web.config file
            string serverIP = WebConfigurationManager.AppSettings["serverIP"];
            string TCPPort = WebConfigurationManager.AppSettings["TCPPort"];
            string DBName = WebConfigurationManager.AppSettings["DBName"];
            string DBLogin = WebConfigurationManager.AppSettings["DBLogin"];
            string DBPassword = WebConfigurationManager.AppSettings["DBPassword"];

            // New DBConnection instance
           
            DBConnection connection = new DBConnection(serverIP, TCPPort, DBName, DBLogin, DBPassword);

            if (motionActivatedU)
                motionActivatedString = "yes";

            // To set the SQL sentence:update motionActivated attribute in ACTIVE_USERS table
            connection.setQueryToCommand("UPDATE ACTIVE_USERS set motionActivated='" + motionActivatedString + "'WHERE login='" + login + "';");

            connection.executeSqlSentence();

            // To set the SQL sentence:update name,surname,password and email address given the login in USERM table
            connection.setQueryToCommand("UPDATE USERM set name='" + newName + "',surname='" + newSurname + "',email='" + newEmail + "',motionActivated='" + motionActivatedString + "'WHERE login='" + login + "';");

            connection.executeSqlSentence();

            // To update user object
            name = newName;
            surname = newSurname;
            email = newEmail;
            motionActivated = motionActivatedU;
           
            if (connection != null)
                if (connection.getConnection().State == ConnectionState.Open)
                    connection.closeConnection();

        }

        public void logOut()
        {
            String input;

            // Get DB parameters from web.config file
            string serverIP = WebConfigurationManager.AppSettings["serverIP"];
            string TCPPort = WebConfigurationManager.AppSettings["TCPPort"];
            string DBName = WebConfigurationManager.AppSettings["DBName"];
            string DBLogin = WebConfigurationManager.AppSettings["DBLogin"];
            string DBPassword = WebConfigurationManager.AppSettings["DBPassword"];




            // New DBConnection instance
            DBConnection connection = new DBConnection(serverIP,TCPPort,DBName,DBLogin,DBPassword);

            if (motionActivated)
                // To update the user from the ACTIVE_USERS table: set isConnected ="No" and accessAt= "null"
                connection.setQueryToCommand("UPDATE ACTIVE_USERS SET isConnected='no',accessAt=NULL,permissionToMove='no',servoTime='-1',firstServoTime='-1' WHERE login='" + login + "';");
            else
                // To delete the user from the ACTIVE_USERS table because motion detection is not activated
                connection.setQueryToCommand("DELETE FROM ACTIVE_USERS WHERE login='" + login + "';");

            connection.executeSqlSentence();

            if (connection != null)
                if (connection.getConnection().State == ConnectionState.Open)
                    connection.closeConnection();

        }


        /// <summary>
        /// Select motion episodes happened in the selected day in the calendar
        /// </summary>
        /// <param name="selectedDay">selected day</param>

        public void pickDay(DateTime selectedDay)
        {       
            motionEpisode motionEpisodeAux = new motionEpisode();
            ArrayList motionEpisodesAux = new ArrayList();
           
            /* An ArrayList of motionEpisodes has been chosen instead of creating
             * a motionEpisode for each episode existing in the DB. The reason is because
             * with an arraylist, there is just one access to the DB. In the other case
             * a new DB connection is needed for each motionEpisode*/

            /* Using an empty motionEpisode object, we get an array which contains all motion episodes
             * happenned in the selected day*/

            motionEpisodesAux = motionEpisodeAux.getMotionEpisodes(selectedDay);

            // The user's attribute motionEpisodes has now all motion episodes happenned in "selectedDay"
            motionEpisodes = null;
            motionEpisodes = new ArrayList();
            motionEpisodes = (ArrayList)motionEpisodesAux.Clone();

           
        }

        /// <summary>
        /// Get motion images related to the motion episode seleceted in the drowdownlist
        /// </summary>
        /// <param name="episodeNumber">episode number</param>
     
        public void pickEpisode(int episodeNumber)
        {       
            // Get motion images related to the motion episode selected
            ((motionEpisode)motionEpisodes[episodeNumber]).getMotionImages();
        }

       
        /// <summary>
        /// Delete motion episode selected in the drop down list
        /// </summary>
        /// <param name="episodeNumber">episode number</param>
     
        public void deleteEpisode(int episodeNumber)
        {
            // Get motionEpisodes[episodeNumber] from motionEpisodes ArrayList
            ((motionEpisode)motionEpisodes[episodeNumber]).deleteMotionImages();
            // motion episode equals to null in motion episode array attribute for current user
            //motionEpisodes[episodeNumber] = null;

        }

        // REturn motionEpisodes array
        /// <summary>
        /// Returns an array of motion episode objects related to the current user object
        /// </summary>
        /// <returns>array of motion episode objects related to the current user object</returns>

        public ArrayList getmotionEpisodes()
        {
            return motionEpisodes;
        }

       
        /// <summary>
        /// Fill live Image object in current user instance with the most recent live image
        /// </summary>

        public void receiveLiveImages()
        {
            // Get live image from live image class
            livImage.getLiveImage();

        }

        /// <summary>
        /// Get live Image object un current user instance with the most recent live image
        /// </summary>
        /// <returns>most recent live image object </returns>

        public liveImage getLiveImage()
        {
            return livImage;
        }


        /// <summary>
        /// Request new camera position in ACTIVE_USERS table. The user wants to move the camera upwards,downwards,to the right or
        /// to the left
        /// </summary>
        /// <param name="direction">up,down,right,left</param>
       
        public void setServoPosition(string direction)
        {
          
            // Get DB parameters from web.config file
            string serverIP = WebConfigurationManager.AppSettings["serverIP"];
            string TCPPort = WebConfigurationManager.AppSettings["TCPPort"];
            string DBName = WebConfigurationManager.AppSettings["DBName"];
            string DBLogin = WebConfigurationManager.AppSettings["DBLogin"];
            string DBPassword = WebConfigurationManager.AppSettings["DBPassword"];

            // New DBConnection instance

           DBConnection connection = new DBConnection(serverIP, TCPPort, DBName, DBLogin, DBPassword);
           
            // Insert new requested position for the current user. To insert the new direction, the user must have permission to move
            if (direction.Equals("down"))
                connection.setQueryToCommand("UPDATE ACTIVE_USERS  SET servoDirection='down' ,servoTime='" + DateTime.Now.ToString() + "' WHERE login='" + login + "' AND permissionToMove='yes';");
            else if (direction.Equals("up"))
                connection.setQueryToCommand("UPDATE ACTIVE_USERS  SET servoDirection='up' ,servoTime='" + DateTime.Now.ToString() + "' WHERE login='" + login + "' AND permissionToMove='yes';");
            else if (direction.Equals("left"))
                connection.setQueryToCommand("UPDATE ACTIVE_USERS  SET servoDirection='left' ,servoTime='" + DateTime.Now.ToString() + "' WHERE login='" + login + "' AND permissionToMove='yes';");
            else
                connection.setQueryToCommand("UPDATE ACTIVE_USERS  SET servoDirection='right' ,servoTime='" + DateTime.Now.ToString() + "' WHERE login='" + login + "' AND permissionToMove='yes';");

            // Execute SQL sentence
            connection.executeSqlSentence();

            if (connection != null)
                if (connection.getConnection().State == ConnectionState.Open)
                    connection.closeConnection();

        }

        /// <summary>
        /// Private attributes
        /// </summary>
        ///

        private String login; // User's login
        private String name; // user's name
        private String surname; // user's surname
        private String password; // user's password
        private String email; // user's e-mail
        private String lastAccess; // user's last access to the system
        private String role; // user's role: administrator or client
        private Boolean motionActivated; // user's motion ACtivated value
        private Camera cam; // user's camera reference
        private ArrayList motionEpisodes; // user's motion Episodes reference
        private liveImage livImage; // user's live Image reference
       
       
       
    }

    Sunday, June 11, 2006 9:45 AM
  • User847786346 posted

    Greetings,

     I have the same exact problem. I am building an image slideshow and manager tool to maintain it. Images are categorized within a "Gallery" and subcategorized within a "Slideshow". The directory structure is: /galleries/Gallery_Name/Slideshow_Name/. I maintain separateness by storing the image uploads in the respective galleries/Gallery/Slideshow directory.

     When user modifies a Gallery or Slideshow, directories may be added, moved or deleted, along with contained image files.

     I was using session variables to hold the currentGallery and currentSlideshow, but found that as soon as I modified a Gallery or Directory in such a way that a directory was added, moved or deleted, my session was clearing.

    It's a shame this behavior isn't better documented. File operations are a common procedure and this is a big hole to fall into without knowing in advance that your session structure (assuming you are using InProc) will fail.

    So, my idea to workaround this issue, for those of us who don't want to (or can't - for whatever reason) change our sessionState mode, would be to enlist the aid of the ViewState to hold our session values (temporarily) until the next postback, when we can check a ViewState variable flag (Session_ViewState_Bridge=true), extract our 'bridged' variables, reinstate them into session variables and clear them from the ViewState.

    This will burden the viewstate sent to the page, slowing the return to the browser, but, from what I understand, viewstate can hold complex objects, which could be a feasible fix, for a short-term problem.

     Any Ideas or comments about whether or not somebody thinks this is a feasible workaround?

    Cheers,

    Stephen

    Thursday, March 20, 2008 6:20 PM
  • User847786346 posted

    Here is a solution I implemented to fulfill my suggested idea. This compiles and runs, but if somebody can add to this, please do!

     

    /// <summary>
    /// Use this method before page unload when you know that the session will be cleared
    /// because you have done file create/delete/move operations
    /// </summary>

    protected void bridgeSessionViewState()
    {
    // create the ViewState keys that will temporarily hold our Session variables
    ViewState["Session_ViewState_Bridge"] = true;
    foreach (string key in Session.Keys)
    {
    ViewState[
    "Session_Bridge_" + key] = Session[key];
    }
    }

    /// <summary>
    /// Use this method somewhere early on in the page load, if IsPostBack == true, to restore your
    /// session variables after a bridging action was performed
    /// </summary>
    protected void unBridgeSessionViewState()
    {
    if (ViewState["Session_ViewState_Bridge"] is Boolean)
    {
    if (Convert.ToBoolean(ViewState["Session_ViewState_Bridge"]) == true)
    {
    ArrayList sessionViewStateBridgeKeys = new ArrayList();
    foreach (string vsKey in ViewState.Keys)
    {
    // find the bridged ViewState keys, and recreate the Session entries
    if (vsKey.StartsWith("Session_Bridge_"))
    {
    string sessionKeyName = vsKey.Replace("Session_Bridge_", "");
    Session[sessionKeyName] = ViewState[vsKey];
    sessionViewStateBridgeKeys.Add(vsKey);
    }
    }

    // remove the ViewState entries the bridging operation created
    for (int i = 0; i < sessionViewStateBridgeKeys.Count; i++)
    {
    string key = sessionViewStateBridgeKeys[i].ToString();
    ViewState.Remove(key);
    }
    }
    }

    }

    Thursday, March 20, 2008 8:08 PM