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

时间:2012-05-08 00:30:51

标签: c# json.net

我有一个包装列表,如下所示:

[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; }
    }
}

我可以序列化客户,但忽略ISerializable上的OrderManager界面。如果我从JsonObject删除OrderManager属性(可能是阻止使用ISerializable的那个),OrderManager将被视为数组和ISerializable接口仍被忽略。

我尝试使用ICollection代替IEnumerableJSON.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;          
}

1 个答案:

答案 0 :(得分:3)

这个答案可能会迟到,但是:

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

您可以通过使用此覆盖实现从DefaultContractResolver继承的自己的合约解析程序来覆盖此行为:

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

        return base.CreateContract(objectType);
    }

最好使用一些更好的逻辑,但是在根目录下这将导致实现ISerializableIEnumerable的对象首先使用ISerializable实现。