我花了很长时间试图解决这个问题,所以我会在这里张贴以防其他人犯同样的错误。
因此,为了复制这种情况,我只有几个基本继承的类:
public abstract class Foo
{
public string Name { get; set; }
}
public class Bar : Foo
{
public int SomethingSpecial { get; set; }
}
public class Baz : Foo
{
public string SomethingMundane { get; set; }
}
现在,我希望能够获取一个json字符串,并解析Foo
的具体实现,而不事先知道json代表哪种类型。 JSON.Net通过使用 $ type 变量来查找对象的类型来处理这个问题:
{
"$type": "MyNamespace.Bar",
"Name": "Resources",
"SomethingSpecial": 42
}
反序列化对象时,您可能希望在JsonSerializerSettings中指定类型处理选项和自定义绑定器,但这是可选的。
我遇到的问题是,当从Web客户端发布json时,该对象没有被反序列化,而是抛出异常,或者在ASP.Net中的POST参数的情况下,该值刚刚到来在null
中。
答案 0 :(得分:2)
这里的问题是Newtonsoft.Json(至少,版本I' m使用 - 9.0.1)期望 $ type 元素是第一个对象的元素,当它处于任何其他位置时将忽略它。所以下面的json虽然在技术上等同于问题中的json,但是不起作用:
{
"Name": "Resources",
"$type": "MyNamespace.Bar",
"SomethingSpecial": 42
}
这是一个设置,虽然它可能会对性能产生影响:
new JsonSerializerSettings
{
// $type no longer needs to be first
MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead
}
值得注意的是,如果您使用JavaScript的JSON.stringify
功能,属性通常按照首次分配给对象的顺序写出,所以您也可以确保你要做的第一件事是分配 $ type 。