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; }
}
}
我可以序列化客户,但是OrderManager上的ISerializable接口将被忽略.如果我从OrderManager中删除JsonObject属性(可能是阻止使用ISerializable的原因),那么OrderManager将被视为一个数组,并且仍会忽略ISerializable接口.
我尝试使用ICollection而不是IEnumerable:
JSON.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;
}
解决方法:
这个答案可能晚了,但是:
这是因为它在检查ISerializable的继承之前先检查IEnumerable的继承,因此它将使用Enumerable接口首先将对象拉出.
您可以通过实现继承自DefaultContractResolver的合同解析器来覆盖此行为:
protected override JsonContract CreateContract(Type objectType)
{
if (typeof(ISerializable).IsAssignableFrom(objectType))
return CreateISerializableContract(objectType);
return base.CreateContract(objectType);
}
最好使用一些更好的逻辑,但是从根本上讲,这将导致实现ISerializable和IEnumerable的对象首先使用ISerializable实现.
标签:json-net,c 来源: https://codeday.me/bug/20191201/2080219.html