我有2个班这样
class A: Base
{
public string CommonField;
public int IntField;
}
class B: Base
{
public string CommonField;
public double DoubleField;
}
我序列A
实例与类型名处理
{
"$type": "MyApp.A, MyApp",
"CommonField": "SomeValue",
"IntField": 123,
"SomeBaseField": 321
}
什么是从此得到B
实例的最简单的方法?在问你为什么之前,它是关于导入A
作为B
(它们具有基本属性和那些名称与你所看到的匹配,所以这个操作是合理的)。
尝试反序列化给JSON作为B
将抛出
Newtonsoft.Json.JsonSerializationException: Type specified in JSON 'MyApp.A, MyApp, Version=0.0.1.1, Culture=neutral, PublicKeyToken=null' is not compatible with 'MyApp.B, MyApp, Version=0.0.1.1, Culture=neutral, PublicKeyToken=null'. Path '$type', line 2, position 42.
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ResolveTypeName(JsonReader reader, Type& objectType, JsonContract& contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, String qualifiedTypeName)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadMetadataProperties(JsonReader reader, Type& objectType, JsonContract& contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue, Object& newValue, String& id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
我能想到以下几点:
- 反序列化JSON作为
A
,创建B
实例并复制所有值(坏) ; - 替换(甚至可以删除?)
$type
在json中,并尝试将其反序列化为B
(更好,仍然不好); - 使用
SerializationBinder
和反序列化JSON作为B
(好):
public class JsonABBinder : DefaultSerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
if (typeName == "MyApp.A")
return typeof(B);
return base.BindToType(assemblyName, typeName);
}
}
有没有更好的办法?在我的场景中,有许多这样的类型,并且有这样的绑定器被人追捕(以及首先阅读json,以确定应用哪个绑定)是非常乏味的。
我正在寻找一种简单的方法来忽略$type
并直接指定想要的类型(泛型方法),因为我知道类型我需要,但我不知道哪种类型是在json中,我想忽略它。
这是非常美丽和简单,谢谢。 – Sinatr