ICollection< T>为什么SerializationBinder调用HashSet<但不在名单上
本文关键字:名单 HashSet 调用 为什么 SerializationBinder ICollection | 更新日期: 2023-09-27 18:08:50
我有一个像这样的对象:
public class MyCollec
{
public ICollection<MyObject> MyCollection { get; set; }
public MyCollec()
{
MyCollection = new List<MyObject>();
}
}
在WebApi我有一个SerializationBinder,在我的webApiConfig:
jsonFormatter.SerializerSettings.Binder = new DefaultSerializationBinder();
当我调用返回all对象的控制器时我得到了这样的结构
{
"MyCollection": [
{
...
},
{
...
}
]
}
但是如果我用hashset
改变构造函数public MyCollec()
{
MyCollection = new HashSet<MyObject>();
}
我的控制器的结果是这样的:
{
"MyCollection": {
"$type": "System.Collections.Generic.HashSet`1[[WebApplication1.Models.MyObject, WebApplication1]], System.Core",
"$values": [
{
...
},
{
...
}
]
}
}
我想知道为什么?是什么差异导致了这种行为?
是否有可能使用HashSet但给出与列表相同的结果?
编辑:@Grundy comment:
TypeNameHandling属性是Auto和from doc:包括。net类型当被序列化的对象的类型与它声明的类型。看来序列化的HashSet和它的不一样声明类型。
这是真的,这是原因,但为什么List不是真的呢?类型与HashSet等ICollection不同
此外,我试图改变TypeNameHandling属性,但没有选项设置$type仅对继承对象…
http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_TypeNameHandling.htm感谢@Grundy的提示。
I keep
jsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto;
我有一个自定义的JsonConverter来改变HashSet
的序列化public class HashSetArrayConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
IEnumerable collectionObj = (IEnumerable)value;
writer.WriteStartObject();
foreach (object currObj in collectionObj)
{
serializer.Serialize(writer, currObj);
}
writer.WriteEndObject();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return serializer.Deserialize(reader, objectType);
}
public override bool CanConvert(Type objectType)
{
var canConvert = IsAssignableToGenericType(objectType, typeof(HashSet<>));
return canConvert;
}
private static bool IsAssignableToGenericType(Type givenType, Type genericType)
{
var interfaceTypes = givenType.GetInterfaces();
if (interfaceTypes.Any(it => it.IsGenericType && it.GetGenericTypeDefinition() == genericType))
{
return true;
}
if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
return true;
Type baseType = givenType.BaseType;
if (baseType == null) return false;
return IsAssignableToGenericType(baseType, genericType);
}
}
并添加到config:
jsonFormatter.SerializerSettings.Converters.Add(new HashSetArrayConverter());