简体   繁体   English

使用Newtonsoft(Json.NET)来序列化System.Diagnostics.EventLogEntry集合

[英]Using Newtonsoft (Json.NET) to serialize System.Diagnostics.EventLogEntry collection

I'm trying to gather windows events that satisfy a particular query and serialize them to JSON so that I can import that collection into a MongoDB database. 我正在尝试收集满足特定查询的Windows事件并将其序列化为JSON,以便可以将该集合导入MongoDB数据库。 This is just me practicing and fooling around, but I got stuck at this point and would love to be able to move forward. 这只是我的练习和鬼混,但我被困在这一点上,很希望能够前进。

The problem: 问题:

When I use JsonConvert.SerializeObject(...) , I certainly do get it to serialize something similar to the object in the sense that there are a few properties that survived: 当我使用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);
    }
}

Output: 输出:

{
    "DataBuffer": "<seemingly-random, long string>",
    "LogName": "Application",
    "MachineName": "<my machine's name>"
}

I can even deserialize the object and get what I expected back. 我什至可以反序列化该对象并得到我期望的结果。 But I really don't want the DataBuffer key-value pair in there, I want the contents of the EventLogEntry to be readable to so that I can parse that information out of MongoDB. 但我真的不希望其中有DataBuffer键值对,而是希望EventLogEntry的内容可读,以便可以从MongoDB中解析该信息。

I've been looking through the documentation for Json.NET , and I'm wondering if I need to do something with creating my own Converter or something, but I'm having a little trouble understanding it all from here. 我一直在浏览Json.NET的文档,并且想知道是否需要做一些事情来创建自己的Converter或其他东西,但是我很难从这里理解所有内容。 There is also talk, in the documentation , of the ability to opt-in/opt-out of serializing particular properties/fields, but it isn't clear to me how one would do that to an object whose declaration/specification wasn't written by one's self. 在文档中也谈到了选择加入/退出序列化特定属性/字段的能力,但是我不清楚如何对没有声明/指定的对象执行此操作。由自己写的。

Any and all help/suggestions are appreciated. 任何和所有帮助/建议表示赞赏。

As far as I know, you cannot deserialize JSON into a new EventLogEntry object. 据我所知,您不能将JSON反序列化为新的EventLogEntry对象。 One reason is that some the properties in EventLogEntry are read-only properties, and the getters for theses properties contain logic to calculate the values, ie, they are not a simple getters that obtain the value from internally stored field. 原因之一是EventLogEntry中的某些属性是只读属性,这些属性的getter包含用于计算值的逻辑,即,它们不是从内部存储字段中获取值的简单getter。

I suggest that you create a special object to hold the data. 我建议您创建一个特殊的对象来保存数据。 Here is an example: 这是一个例子:

public class MyEventLogEntry
{
    public string MachineName { get; set; }
    public DateTime GeneratedTime { get; set; }
    public string Message { get; set; }
    public long InstanceId { get; set; } 
}

You can put in this class the event properties that you are interested in. They can even have different names than the ones inside EventLogEntry . 您可以在此类中放入您感兴趣的事件属性。它们甚至可以具有与EventLogEntry内部不同的名称。

You can use AutoMapper to easily convert from EventLogEntry to MyEventLogEntry . 您可以使用AutoMapper轻松地从EventLogEntry转换为MyEventLogEntry Or you can do it manually if you want. 或者,您也可以根据需要手动进行操作。

Here is a code sample that uses AutoMapper: 这是使用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);

Please note that the call to AutoMapper.Mapper.CreateMap needs to done only once (eg at the start of your application). 请注意,对AutoMapper.Mapper.CreateMap的调用只需完成一次(例如,在您的应用程序开始时)。

You can use MyEventLogEntry when you want to read/write from/to the database. 当您想从数据库中读取/写入数据库时​​,可以使用MyEventLogEntry

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

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