简体   繁体   中英

Serialize dictionary to XML C#

I have a dictionary where I have to add an object while a User log on and need to remove the object while user log off in windows. I am also serializing the dictionary to xml. As I am new to C# as well as windows service I have some doubts.

Here is my code.

   public class UserSessionCapturePlugin : IInformServiceHandler
   {
        public Dictionary<int, UserSessionInfo> UserSessionLookupTable = new Dictionary<int, UserSessionInfo>();

        public void OnSessionChange(SessionChangeDescription changeDescription)
        {
            switch (changeDescription.Reason)
            {
                //Case of Logon
                case SessionChangeReason.SessionLogon:
                    //CreateRunningProcessesLog("UserSession-SessionLogon");

                    UserSession userSessionLogin = new UserSession()
                    {
                        UserName = MachineHelper.GetUsername(),
                        UserGuid = MachineHelper.GetUserGuid(),
                        MachineGuid = MachineHelper.GetMachineGUID(),
                        LoginTime = DateTime.Now.ToUniversalTime(),
                        SessionGuid = Guid.NewGuid(), //New Guid generated for tracking the UserSession, this will be created on on logon
                        IsReadable = false,
                        SessionId = changeDescription.SessionId,
                    };

                    UserSessionInfo userSessionInfoLogin = new UserSessionInfo()
                    {
                        UserName = MachineHelper.GetUsername(),
                        SessionGuid = userSessionLogin.SessionGuid,
                        IsActiveUser = true,
                        SessionId = changeDescription.SessionId,
                        LoginTime = userSessionLogin.LoginTime,
                        State = RowState.Added,
                    };  

                        UserSessionLookupTable.Add(userSessionInfoLogin.SessionId, userSessionInfoLogin);
                        XmlSerializer serializer = new XmlSerializer(typeof(Dictionary<Guid, UserSessionInfo>));
                        TextWriter textWriter = new StreamWriter(@"UserSessionLookupDictionarySerialized.xml");
                        serializer.Serialize(textWriter, UserSessionLookupTable);
                        textWriter.Close();


                //Case of Logoff
                case SessionChangeReason.SessionLogoff:
                    UserSession userSessionLogoff = new UserSession()
                    {
                        UserName = MachineHelper.GetUsername(),
                        UserGuid = MachineHelper.GetUserGuid(),
                        MachineGuid = MachineHelper.GetMachineGUID(),
                        LogOffTime = DateTime.Now.ToUniversalTime(),
                        IsReadable = true,
                        SessionId = changeDescription.SessionId,
                    };

                    UserSessionLookupTable.Remove(userSessionLogoff.SessionId);
                    XmlSerializer serializer = new XmlSerializer(typeof(Dictionary<Guid, UserSessionInfo>));
                        TextWriter textWriter = new StreamWriter(@"UserSessionLookupDictionarySerialized.xml");
                        serializer.Serialize(textWriter, UserSessionLookupTable);
                        textWriter.Close();
                    break;
            }
        }
    }

But I have the below doubts

  1. If multiple users are logging on, is this xml would be replaced with details of last login user or an additional entry of the new user will be added?

  2. While on logoff does the user details will be removed from the xml as well or any other methods (like deserializing and removing the entry) is needed?

I am currently unable to debug or run the code thats why I am posting it here.

As UserSessionLookupTable is non-static object so its lifespan is with the life span of parent. As long you are using same instance of UserSessionCapturePlugin for all users, this will hold record of all the users.

If you are creating different instance of UserSessionLookupTable for each request that will hold only record of last user.

Also XmlSerializer can't serialize Dictionary directly .

To correct the behaviour and keep record of all the user sessions, I suggest to modify the way you are saving session session info.

  • Before saving new user session info, first load and deserialize existing xml, add new record in it, serialize again and save to file. (You need to make sure if that is first time, file will not exists so handle that)
  • Before removing user session info, first load and deserialize existing xml, remove record that you want to remove, serialize again and save it back to file.

Here is some snippet

Dictionary<Guid, UserSessionInfo> LoadUserSessionData()
{
    try
    {
        var serializer = new XmlSerializer(typeof(KeyValuePair<Guid, UserSessionInfo>[]));

        using (var stream = new FileStream(@"UserSessionLookupDictionarySerialized.xml", FileMode.Open))
        {
             var sessionData = (KeyValuePair<Guid, UserSessionInfo>[])serializer.Deserialize(stream)
             return sessionData.ToDictionary(i => i.Key, i => i.Value);
        }
    }
    catch (FileNotFoundException)
    {
        return new Dictionary<int, UserSessionInfo>();
    }
}


void SaveUserSessionData(Dictionary<Guid, UserSessionInfo> sessionData)
{
    var serializer = new XmlSerializer(typeof(KeyValuePair<Guid, UserSessionInfo>[]));

    using (var stream = new FileStream(@"UserSessionLookupDictionarySerialized.xml", FileMode. OpenOrCreate))
    {
         serializer.Serialize(stream, sessionData.ToArray());
    }
}

After that OnSessionChange will looks like this

public void OnSessionChange(SessionChangeDescription changeDescription)
{
    switch (changeDescription.Reason)
    {
        //Case of Logon
        case SessionChangeReason.SessionLogon:
            //CreateRunningProcessesLog("UserSession-SessionLogon");

            UserSession userSessionLogin = new UserSession()
            {
                UserName = MachineHelper.GetUsername(),
                UserGuid = MachineHelper.GetUserGuid(),
                MachineGuid = MachineHelper.GetMachineGUID(),
                LoginTime = DateTime.Now.ToUniversalTime(),
                SessionGuid = Guid.NewGuid(), //New Guid generated for tracking the UserSession, this will be created on on logon
                IsReadable = false,
                SessionId = changeDescription.SessionId,
            };

            UserSessionInfo userSessionInfoLogin = new UserSessionInfo()
            {
                UserName = MachineHelper.GetUsername(),
                SessionGuid = userSessionLogin.SessionGuid,
                IsActiveUser = true,
                SessionId = changeDescription.SessionId,
                LoginTime = userSessionLogin.LoginTime,
                State = RowState.Added,
            };  

            var userSessionLookupTable = LoadUserSessionData();
            userSessionLookupTable.Add(userSessionInfoLogin.SessionId, userSessionInfoLogin);
            SaveUserSessionData(userSessionLookupTable);
            break;

        //Case of Logoff
        case SessionChangeReason.SessionLogoff:
            UserSession userSessionLogoff = new UserSession()
            {
                UserName = MachineHelper.GetUsername(),
                UserGuid = MachineHelper.GetUserGuid(),
                MachineGuid = MachineHelper.GetMachineGUID(),
                LogOffTime = DateTime.Now.ToUniversalTime(),
                IsReadable = true,
                SessionId = changeDescription.SessionId,
            };

            var userSessionLookupTable = LoadUserSessionData();
            userSessionLookupTable.Remove(userSessionLogoff.SessionId);
            SaveUserSessionData(userSessionLookupTable);
            break;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM