Сериализация словаря в XML C#

У меня есть словарь, в котором я должен добавить объект, когда пользователь входит в систему, и мне нужно удалить объект, когда пользователь выходит из системы в Windows. Я также сериализую словарь в XML. Поскольку я новичок в C#, а также служба Windows, у меня есть некоторые сомнения.

Вот мой код

   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;
            }
        }
    }

Но у меня есть следующие сомнения

  1. Если несколько пользователей входят в систему, будет ли этот xml заменен данными о последнем входе в систему или будет добавлена ​​дополнительная запись о новом пользователе?

  2. При выходе из системы будут ли удаляться пользовательские данные из xml или же нужны какие-либо другие методы (например, десериализация и удаление записи)?

В настоящее время я не могу отладить или запустить код, поэтому я публикую его здесь.

1 ответ

Решение

Как UserSessionLookupTable является нестатичным объектом, поэтому срок его службы зависит от продолжительности жизни родителя. Пока вы используете один и тот же экземпляр UserSessionCapturePlugin для всех пользователей будет храниться запись всех пользователей.

Если вы создаете другой экземпляр UserSessionLookupTable за каждый запрос, который будет содержать только запись последнего пользователя.

Также XmlSerializer не может сериализовать словарь напрямую.

Чтобы исправить поведение и вести учет всех пользовательских сеансов, я предлагаю изменить способ сохранения информации о сеансах.

  • Перед сохранением информации о новом сеансе пользователя сначала загрузите и десериализуйте существующий XML, добавьте в него новую запись, снова сериализуйте и сохраните в файл. (Вы должны убедиться, что если это первый раз, файл не будет существовать, так что обработайте это)
  • Перед удалением информации о сеансе пользователя сначала загрузите и десериализуйте существующий xml, удалите запись, которую вы хотите удалить, снова сериализуйте и сохраните ее обратно в файл.

Вот небольшой фрагмент

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());
    }
}

После этого OnSessionChange будет выглядеть так

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;
    }
}
Другие вопросы по тегам