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

mbu*_*ill 5 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)
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

    private OrderManager _orders
        = new OrderManager();
    public OrderManager Orders
    {
        get { return _orders; }
        set { _orders = value; }
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以序列化客户,但ISerializable接口OrderManager被忽略。如果我从(可能是阻止使用的属性)JsonObject中删除该属性,则该属性将被视为数组,并且该接口仍然被忽略。OrderManagerISerializableOrderManagerISerializable

我尝试使用ICollection而不是IEnumerableJSON.NET无法反序列化包装的集合

由于我的包装集合是类型Order并且我的AddOrder方法接受OrderInfo,所以公开 并没有真正起作用ICollection<Order>。不管怎样,ISerializable接口都被忽略了。

有什么解决方法吗?

更新

只是为了澄清我确实将 IgnoreSerializedInterface 设置为 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;          
}
Run Code Online (Sandbox Code Playgroud)

Are*_*ren 4

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

IEnumerable这是因为它在检查继承之前检查继承,ISerializable因此它会首先使用 Enumerable 接口来提取对象。

您可以通过实现您自己的合约解析器来重写此行为,DefaultContractResolver该解析器继承自此重写:

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

        return base.CreateContract(objectType);
    }
Run Code Online (Sandbox Code Playgroud)

最好有一些更好的逻辑,但这从根本上会导致对象首先实现ISerializableIEnumerable使用 ISerialized 实现。