2012-05-08 3 views
2

У меня есть обернутый список, который выглядит следующим образом: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; } 
    } 
} 

я могу сериализовать клиента, но интерфейс ISerializable на OrderManager игнорируется. Если я удалю атрибут JsonObject из OrderManager (возможно, что предотвращает использование ISerializable) OrderManager рассматривается как массив, а интерфейс ISerializable по-прежнему игнорируется.

Я попытался с помощью ICollection вместо IEnumerable: JSON.NET cannot deserialize a wrapped collection

Поскольку моя завернутые коллекция типа Order и мой AddOrder метод принимает в OrderInfo, он действительно не работает, чтобы выставить ICollection<Order>. В любом случае, интерфейс ISerializable был проигнорирован.

Есть ли способы обхода?

Update

Просто уточнить у меня есть IgnoreSerializableInterface значение ЛОЖЬ.

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;   
} 
+0

Вы пытались переместить экземпляр '_orders' в конструктор' Customer'? – scottm

+0

Просто попробовал это. С атрибутом JsonObject и без него на OrderManager ISerializable все еще игнорировался. – mbursill

+0

Любопытно, если вы добавите атрибут '[Serializable]' и сделаете конструктор для '[JsonObject()] пустым. Я читал об этом немного на сайте doc JSON.NET, и мне интересно, есть ли конфликт, который происходит. Атрибут 'Serializable' имеет тот же эффект, что и' JsonObject (MemberSerialization.Fields) ', согласно документам. –

ответ

3

Этот ответ может быть поздно, но:

Это потому, что он проверяет на наследование IEnumerable перед проверкой наследования ISerializable поэтому он будет использовать Enumerable интерфейс, чтобы вытащить объекты из первого.

Вы можете переопределить это поведение путем реализации собственного контракта распознаватель, унаследованный от DefaultContractResolver этой замены:

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

     return base.CreateContract(objectType); 
    } 

Предпочтительно с некоторой лучшей логикой, но это в корне будет вызывать объекты, которые реализуют ISerializable и IEnumerable использовать сначала выполнить ISERializable.

Смежные вопросы