希望这是一个我忽略的简单修复。我有一个对象传递到一个事件处理程序,我想使用JSON.NET序列化该对象,如下所示:
public void OnEvent(IEventObject foo)
{
// Serialize foo to string/disk here?
var data = JsonConvert.SerializeObject(foo, Formatting.Indented);
}
似乎foo的一个或多个成员是流。我已经认识到Streams不可序列化,因为它们是数据的抽象而不是数据本身。这是有道理的。
我不知道如何序列化这个对象:
有一点需要注意的是,我无法访问IEventObject或其实现,因此无法使用属性标记标记任何这些对象。
我提出的唯一解决方案是将此对象包装在我自己的类中,对其进行适当标记,然后对其进行序列化。稍后我会反序列化回我自己的类,并将其转换为原始对象。我不喜欢这种方法,因为它涉及额外的对象和转换步骤,并且如果可能的话希望避免它。
答案 0 :(得分:15)
默认情况下,Json.NET会尝试序列化流的属性,这不是非常有用。您可以通过创建自己的contract resolver来修改行为。这是一个完全忽略所有Stream
的例子:
public class IgnoreStreamsResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(
MemberInfo member,
MemberSerialization memberSerialization
)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
if (typeof(Stream).IsAssignableFrom(property.PropertyType))
{
property.Ignored = true;
}
return property;
}
}
使用它像:
var bytes = new byte[] { 1, 2, 3 };
var eo = new EventObject { OtherValue = 2, MyStream = new MemoryStream(bytes) };
var s = JsonConvert.SerializeObject(eo,
new JsonSerializerSettings { ContractResolver = new IgnoreStreamsResolver() });
// {"OtherValue":2}
通过修改JsonProperty
的其他属性,您可以进行其他更改。看起来对您最有用的是Converter
,它可以让您指定自己的类来定义如何序列化Stream
(例如将其转换为byte[]
和序列化为base64)。
所有这些都是在不对接口或实现类进行任何更改的情况下完成的。