我有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)
我能想到以下几点:
A
,创建B
的实例并复制所有值(错误); $type
并尝试将其反序列化为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为A
以确定应用哪个绑定器)非常繁琐。
我正在寻找一种简单的方法来忽略$type
并直接指定所需类型(泛型方法),因为我知道我需要的类型,但我不知道json中的哪种类型,我想忽略它
答案 0 :(得分:5)
您可以使用:
new JsonSerializer().TypeNameHandling = TypeNameHandling.None
这将忽略$ type。
答案 1 :(得分:4)
在解除类型设置时传递一些设置是个好主意:
private readonly JsonSerializerSettings _settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.None
};
然后使用它:
var json = JsonConvert.DeserializeObject<object>(jsonString, _settings);
甚至更简单
var json = JsonConvert.DeserializeObject<object>(jsonString, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.None
});