简体   繁体   English

将字典序列化为XML C#

[英]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. 我有一本字典,在其中我必须在用户登录时添加一个对象,并且需要在用户在Windows中注销时删除该对象。 I am also serializing the dictionary to xml. 我也在将字典序列化为xml。 As I am new to C# as well as windows service I have some doubts. 由于我是C#和Windows服务的新手,因此我对此有所怀疑。

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? 如果有多个用户登录,是用上次登录用户的详细信息替换此xml还是添加新用户的其他条目?

  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? 注销时是否还会从xml中删除用户详细信息,或者是否需要其他任何方法(例如反序列化和删除条目)?

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. 由于UserSessionLookupTable是非静态对象,因此其寿命与父对象的寿命相同。 As long you are using same instance of UserSessionCapturePlugin for all users, this will hold record of all the users. 只要您对所有用户使用UserSessionCapturePlugin相同实例,它将保存所有用户的记录。

If you are creating different instance of UserSessionLookupTable for each request that will hold only record of last user. 如果要为每个仅保留最后一个用户记录的请求创建UserSessionLookupTable不同实例。

Also XmlSerializer can't serialize Dictionary directly . XmlSerializer也无法直接序列化Dictionary

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. 在保存新的用户会话信息之前,首先加载并反序列化现有xml,在其中添加新记录,再次序列化并保存到文件。 (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. 删除用户会话信息之前,请先加载并反序列化现有xml,删除要删除的记录,再次进行序列化并将其保存回文件。

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 之后, 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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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