其他分享
首页 > 其他分享> > JSON.NET在集合类型对象上忽略ISerializable

JSON.NET在集合类型对象上忽略ISerializable

作者:互联网

我有一个包装好的清单,看起来像这样:

[JsonObject(MemberSerialization.Fields)]
public class OrderManager : IEnumerable<Order>, ISerializable
{
    public OrderManager()
    { }

    private List<Order> orders = new List<Order>();

    public void AddOrder(OrderInfo orderInfo)
    {
        // do the work of making an order object from an OrderInfo.
        // Add the new order object to the private list of orders
        // orders.Add(order);
    }

    public IEnumerator<Order> GetEnumerator()
    {
        return orders.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return orders.GetEnumerator();
    }

    public OrderManager(SerializationInfo info, StreamingContext context)
    {
        // do custom serialization work here (never gets hit)
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        // do custom serialization work here (never gets hit)
    }
}

我在客户类中包括一个字段实例,如下所示:

[JsonObject(MemberSerialization.Fields)]
public class Customer
{
    public Customer()
    { }

    private OrderManager _orders
        = new OrderManager();
    public OrderManager Orders
    {
        get { return _orders; }
        set { _orders = value; }
    }
}

我可以序列化客户,但是OrderManager上的ISerializable接口将被忽略.如果我从OrderManager中删除JsonObject属性(可能是阻止使用ISerializable的原因),那么OrderManager将被视为一个数组,并且仍会忽略ISerializable接口.

我尝试使用ICollection而不是IEnumerable:
JSON.NET cannot deserialize a wrapped collection

由于我包装的集合的类型为Order,而我的AddOrder方法采用OrderInfo,因此公开ICollection< Order>并不能真正起作用.无论哪种方式,都会忽略ISerializable接口.

有什么解决方法吗?

更新资料

只是为了澄清一下,我确实将IgnoreSerializableInterface设置为false.

private JsonSerializer GetSerializer()
{
    var serializer = new JsonSerializer();

    serializer.TypeNameHandling = TypeNameHandling.Auto;
    serializer.TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;

    var contractResolver = new DefaultContractResolver(true);
    contractResolver.IgnoreSerializableAttribute = false;
    contractResolver.IgnoreSerializableInterface = false;

    serializer.ContractResolver = contractResolver;

    serializer.PreserveReferencesHandling = PreserveReferencesHandling.All;
    serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

    return serializer;          
}

解决方法:

这个答案可能晚了,但是:

这是因为它在检查ISerializable的继承之前先检查IEnumerable的继承,因此它将使用Enumerable接口首先将对象拉出.

您可以通过实现继承自DefaultContractResolver的合同解析器来覆盖此行为:

    protected override JsonContract CreateContract(Type objectType)
    {
        if (typeof(ISerializable).IsAssignableFrom(objectType))
            return CreateISerializableContract(objectType);

        return base.CreateContract(objectType);
    }

最好使用一些更好的逻辑,但是从根本上讲,这将导致实现ISerializable和IEnumerable的对象首先使用ISerializable实现.

标签:json-net,c
来源: https://codeday.me/bug/20191201/2080219.html