【问题标题】:JSON.NET Serialization on an object with a member of type Stream?对具有 Stream 类型成员的对象进行 JSON.NET 序列化?
【发布时间】:2014-06-15 12:57:06
【问题描述】:

希望这是一个我忽略的简单修复。我有一个对象传递给我想使用 JSON.NET 序列化该对象的事件处理程序,如下所示:

public void OnEvent(IEventObject foo)
{
    // Serialize foo to string/disk here?
    var data = JsonConvert.SerializeObject(foo, Formatting.Indented);
}

似乎 foo 的一个或多个成员是流。我已经认识到 Streams 是不可序列化的,因为它们是对数据而不是数据本身的抽象。这是有道理的。

我也不知道如何序列化这个对象:

  • a) 将流转换为数据并对其进行序列化
  • b) 忽略流并序列化剩余成员

对此的一个重要警告是我无权访问 IEventObject 或其实现,因此我无法使用属性标志标记任何这些对象。

我想出的唯一解决方案是将这个对象包装在我自己的类中,适当地标记它,然后将其序列化。后来我会反序列化回我自己的类,并将其转换为原始对象。我不喜欢这种方法,因为它涉及额外的对象和转换步骤,并且希望尽可能避免它。

【问题讨论】:

  • 我遇到了完全相同的问题,别无选择,只能将其包装在我的一个完全可序列化的对象中。如果还有其他选择,我也会很高兴听到它:-)
  • @Bartdude 你可以看看我的回答。
  • @TimS。不幸的是,在我的情况下,我最终不得不实现包装器对象,因为我没有对具体类型的本地访问以反序列化回。否则,接受的答案是解决这个问题的好方法。

标签: c# .net serialization json.net


【解决方案1】:

默认情况下,Json.NET 会尝试序列化流的属性,这不是很有用。您可以通过创建自己的contract resolver 来修改行为。这是一个完全忽略所有Streams 的示例:

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)。

所有这些都是在没有对接口或实现类进行任何更改的情况下完成的。

【讨论】:

  • 这正是我想要的。我会在自己实施和测试后检查。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-09
  • 2012-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-29
  • 1970-01-01
相关资源
最近更新 更多