I have a wrapped list that looks like this:
[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)
}
}
I include a field instance in a customer class like this:
[JsonObject(MemberSerialization.Fields)]
public class Customer
{
public Customer()
{ }
private OrderManager _orders
= new OrderManager();
public OrderManager Orders
{
get { return _orders; }
set { _orders = value; }
}
}
I can serialize a customer but the ISerializable interface on OrderManager is ignored. If I remove the JsonObject attribute from the OrderManager (probably what is preventing ISerializable from being used) the OrderManager is treated as an array and the ISerializable interface is still ignored.
I tried using ICollection instead of IEnumerable:
JSON.NET cannot deserialize a wrapped collection
Since my wrapped collection is of type Order and my AddOrder method takes in OrderInfo, it doesn’t really work to expose ICollection<Order>. Either way, the ISerializable interface was ignored.
Are there any workarounds?
Update
Just to clarify I do have IgnoreSerializableInterface set to 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;
}
This answer might be late but:
This is because it checks for inheritance of
IEnumerablebefore checking for inheritance ofISerializableso it will use the Enumerable interface to pull objects out first.You can override this behavior by implementing your own contract resolver inheriting from
DefaultContractResolverwith this override:Preferably with some better logic, but this at the root will cause objects that implement
ISerializableandIEnumerableto use the ISerializable implementation first.