[英]ICollection<T> Why SerializationBinder is call on HashSet<T> but not on List<T>
I have an object like this : 我有一个这样的对象:
public class MyCollec
{
public ICollection<MyObject> MyCollection { get; set; }
public MyCollec()
{
MyCollection = new List<MyObject>();
}
}
In WebApi i had a SerializationBinder, in my webApiConfig : 在WebApi中,我的webApiConfig中有一个SerializationBinder:
jsonFormatter.SerializerSettings.Binder = new DefaultSerializationBinder();
When I call my controller that return my all object i get a structure like this 当我调用返回我所有对象的控制器时,我得到了这样的结构
{
"MyCollection": [
{
...
},
{
...
}
]
}
But if i change my constructor with an hashset 但是如果我用哈希集更改构造函数
public MyCollec()
{
MyCollection = new HashSet<MyObject>();
}
The result of my controller is like this : 我的控制器的结果是这样的:
{
"MyCollection": {
"$type": "System.Collections.Generic.HashSet`1[[WebApplication1.Models.MyObject, WebApplication1]], System.Core",
"$values": [
{
...
},
{
...
}
]
}
}
I would like understand why ? 我想知道为什么吗? What is the difference which induce this behavior ? 导致这种行为的区别是什么?
Is-it possible to use a HashSet but give the same result like with the list ? 是否可以使用HashSet,但给出与列表相同的结果?
EDIT : 编辑:
@Grundy comment : @Grundy评论:
TypeNameHandling property is Auto and from doc: Include the .NET type name when the type of the object being serialized is not the same as its declared type. TypeNameHandling属性是Auto,来自doc:当要序列化的对象的类型与其声明的类型不同时,请包括.NET类型名称。 So seems HashSet serialized is not the same as its declared type. 因此,似乎HashSet序列化与其声明的类型不同。
It's true, it's the reason, but why it's not true for List ? 是的,这是事实,但是对于List来说,事实并非如此? The type is different of ICollection like HashSet... ICollection的类型与HashSet等不同。
Moreover, I try to change TypeNameHandling property but there no option for set $type only on inherited objects... 此外,我尝试更改TypeNameHandling属性,但是没有设置set type仅在继承对象上的选项。
http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_TypeNameHandling.htm http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_TypeNameHandling.htm
Thanks to @Grundy for the clue. 感谢@Grundy提供的线索。
I keep 我一直
jsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto;
and I had a custom JsonConverter to change the serialization of HashSet 我有一个自定义的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);
}
}
and add it in config : 并将其添加到config中:
jsonFormatter.SerializerSettings.Converters.Add(new HashSetArrayConverter());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.