将字典序列化为 XML C#

Serialize dictionary to 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 中删除,或者是否需要任何其他方法(如反序列化和删除条目)?

我目前无法调试或 运行 代码,这就是我将其发布在这里的原因。

由于UserSessionLookupTable是非静态对象,所以它的生命周期与父对象的生命周期相同。只要您为所有用户使用相同的 UserSessionCapturePlugin 实例,这将保留所有用户的记录。

如果您为每个请求创建不同的 UserSessionLookupTable 实例,它将只保存最后一个用户的记录。

XmlSerializer不能serialize Dictionary directly.

要纠正该行为并记录所有用户会话,我建议修改您保存会话会话信息的方式。

  • 在保存新的用户会话信息之前,首先加载并反序列化现有的 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;
    }
}