将字典序列化为 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;
}
}
}
但我有以下疑惑
如果有多个用户登录,xml 是否会被上次登录用户的详细信息替换,或者是否会添加新用户的附加条目?
注销时,用户详细信息是否也会从 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;
}
}
我有一个字典,我必须在用户登录时添加一个对象,而在 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;
}
}
}
但我有以下疑惑
如果有多个用户登录,xml 是否会被上次登录用户的详细信息替换,或者是否会添加新用户的附加条目?
注销时,用户详细信息是否也会从 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;
}
}