JSON.NET ignores ISerializable on collection type object
c#, json.net
Solution
This answer might be late but:
This is because it checks for inheritance of `IEnumerable` before checking for inheritance of `ISerializable` so it will use the Enumerable interface to pull objects out first.
You can override this behavior by implementing your own contract resolver inheriting from `DefaultContractResolver` with this override:
protected override JsonContract CreateContract(Type objectType)
{
if (typeof(ISerializable).IsAssignableFrom(objectType))
return CreateISerializableContract(objectType);
return base.CreateContract(objectType);
}
Preferably with some better logic, but this at the root will cause objects that implement `ISerializable` and `IEnumerable` to use the ISerializable implementation first.
Problem
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; } ```