I have a c# class which looks like
public class Node {
public int Id { get; set; }
/** Properties omitted for sake of brevity **/
public Node ParentNode { get; set; }
}
From a browser, I submitted a JSON object as follows
{"Id":1, "ParentNode":1}
Where the value 1 assigned to the ParentNode property representes a database identifier. So, in order to bind properly to my model, i need to write a custom JSON converter
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;
}
}
Because i get a "Current JsonReader item is not an object: Integer. Path ParentNode'", how can adapt the ReadJson method in order to bind the ParentNode property or anything else which needs custom conversion ?
UPDATE
I have seen JsonPropertyAttribute whose API documentation states
Instructs the JsonSerializer to always serialize the member with the specified name
However, how can i instruct programatically a JsonSerializer - in my case, in the ReadJson method - to use a given JsonPropertyAttribute ?
http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonPropertyAttribute.htm
I think the issue here is that the parsing becomes recursive due to a Node
containing a Node
in the form of the ParentNode
property.
On the call to serializer.Populate(jObject.CreateReader(), node);
the serializer will hit the ParentNode
property which is of type Node
and it will then attempt to parse that using your NodeJsonConverter
. At that point the reader has moved on and you no longer have a StartObject
but insted you have an Integer
. I think you can check the reader.TokenType
property to see if you are in the first call or the subsequent call and handle it accordingly:
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With