我有一个C#类,看起来像
public class Node {
public int Id { get; set; }
/** Properties omitted for sake of brevity **/
public Node ParentNode { get; set; }
}
在浏览器中,我提交了一个JSON对象,如下所示
{"Id":1, "ParentNode":1}
分配给ParentNode属性的值1表示数据库标识符。因此,为了正确绑定(bind)到我的模型,我需要编写一个自定义JSON转换器
public class NodeJsonConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
/** Load JSON from stream **/
JObject jObject = JObject.Load(reader);
Node node = new Node();
/** Populate object properties **/
serializer.Populate(jObject.CreateReader(), node);
return node;
}
}
因为我收到“当前JsonReader项不是对象:Integer。Path ParentNode'”的信息,所以如何适应ReadJson方法以绑定(bind)ParentNode属性或需要自定义转换的任何其他项?
更新
我见过JsonPropertyAttribute,其API文档说明
但是,如何以编程方式指示 JsonSerializer (在我的情况下为ReadJson方法)使用给定的JsonPropertyAttribute?
http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonPropertyAttribute.htm
最佳答案
我认为这里的问题是由于包含Node
属性形式的Node
的ParentNode
导致解析变得递归。
在调用serializer.Populate(jObject.CreateReader(), node);
时,序列化程序将命中ParentNode
类型的Node
属性,然后它将尝试使用NodeJsonConverter
解析该属性。那时,读者已经前进了,您不再有StartObject
,而是提示您有了Integer
。我认为您可以检查reader.TokenType
属性以查看您是在第一个调用中还是在后续调用中,并相应地进行处理:
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
Node node = new Node();
if (reader.TokenType == JsonToken.StartObject)
{
//initial call
//here we have the object so we can use Populate
JObject jObject = JObject.Load(reader);
serializer.Populate(jObject.CreateReader(), node);
}
else
{
//the subsequent call
//here we just have the int which is the ParentNode from the request
//we can assign that to the Id here as this node will be set as the
//ParentNode on the original node from the first call
node.Id = (int)(long)reader.Value;
}
return node;
}