0

我有一本字典,我必须在用户登录时添加一个对象,并且需要在用户在 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 中删除,或者是否需要任何其他方法(如反序列化和删除条目)?

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

4

1 回答 1

2

UserSessionLookupTable非静态对象一样,它的寿命与父对象的寿命相同。只要您UserSessionCapturePlugin对所有用户使用相同的实例,这将保存所有用户的记录。

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

XmlSerializer不能直接序列化 Dictionary

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

  • 在保存新的用户会话信息之前,首先加载和反序列化现有的 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;
    }
}
于 2016-03-24T06:17:41.060 回答