我正在尝试收集满足特定查询的windows事件,并将它们序列化为JSON,以便将该集合导入MongoDB数据库。这只是我在练习和闲逛,但我在这一点上陷入了困境,我希望能够继续前进。
问题是:
当我使用JsonConvert.SerializeObject(...)
时,我肯定会让它序列化类似于对象的东西,因为有一些属性幸存下来:
public class EventSerializer
{
public static void Serialize(EventLogEntry eventLogEntry)
{
var traceWriter = new MemoryTraceWriter();
JsonConvert.SerializeObject(eventLogEntry, Formatting.Indented, new JsonSerializerSettings
{
TraceWriter = traceWriter
});
Console.WriteLine(traceWriter);
}
}
输出:
{
"DataBuffer": "<seemingly-random, long string>",
"LogName": "Application",
"MachineName": "<my machine's name>"
}
我甚至可以反序列化对象并得到我所期望的结果。但我真的不希望DataBuffer键值对在那里,我希望EventLogEntry
的内容是可读的,这样我就可以从MongoDB中解析这些信息。
我一直在查看Json.NET
的文档,我想知道是否需要创建自己的Converter
或其他什么,但我在理解这一切时遇到了一些困难。文档中也谈到了选择加入/选择退出序列化特定属性/字段的能力,但我不清楚如何对声明/规范不是自己编写的对象执行此操作。
感谢您的任何帮助/建议。
据我所知,您无法将JSON反序列化为新的EventLogEntry
对象。一个原因是EventLogEntry
中的一些属性是只读属性,这些属性的getter包含计算值的逻辑,即它们不是从内部存储的字段中获取值的简单getter。
我建议您创建一个特殊的对象来保存数据。这里有一个例子:
public class MyEventLogEntry
{
public string MachineName { get; set; }
public DateTime GeneratedTime { get; set; }
public string Message { get; set; }
public long InstanceId { get; set; }
}
您可以将感兴趣的事件属性放在这个类中。它们甚至可以与EventLogEntry
中的名称不同。
您可以使用AutoMapper轻松地从EventLogEntry
转换为MyEventLogEntry
。如果您愿意,也可以手动执行。
下面是一个使用AutoMapper的代码示例:
AutoMapper.Mapper.CreateMap<EventLogEntry, MyEventLogEntry>()
.ForMember(dst => dst.InstanceId, opt => opt.MapFrom(src => src.InstanceId))
.ForMember(dst => dst.Message, opt => opt.MapFrom(src => src.Message))
.ForMember(dst => dst.GeneratedTime, opt => opt.MapFrom(src => src.TimeGenerated))
.ForMember(dst => dst.MachineName, opt => opt.MapFrom(src => src.MachineName));
EventLog log = new EventLog("Application");
EventLogEntry entry = log.Entries[0];
MyEventLogEntry my_entry = AutoMapper.Mapper.Map<EventLogEntry, MyEventLogEntry>(entry);
string json = JsonConvert.SerializeObject(my_entry);
MyEventLogEntry deserialized_entry = JsonConvert.DeserializeObject<MyEventLogEntry>(json);
请注意,对AutoMapper.Mapper.CreateMap
的调用只需要完成一次(例如,在应用程序开始时)。
当您想从数据库读取/向数据库写入时,可以使用MyEventLogEntry
。