在c#Web Api中反序列化JSON对象时如何绑定给定的属性?

Art*_*ald 5 c# asp.net json asp.net-web-api

我有一个看起来像的#class类

public class Node {

    public int Id { get; set; }

    /** Properties omitted for sake of brevity **/

    public Node ParentNode { get; set; }

}
Run Code Online (Sandbox Code Playgroud)

在浏览器中,我提交了一个JSON对象,如下所示

{"Id":1, "ParentNode":1}
Run Code Online (Sandbox Code Playgroud)

分配给ParentNode属性的值1表示数据库标识符.因此,为了正确绑定到我的模型,我需要编写一个自定义的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

因为我得到"当前JsonReader项不是对象:Integer.Path ParentNode'",如何调整ReadJson方法以绑定ParentNode属性或需要自定义转换的任何其他内容?

UPDATE

我见过其API文档所述的JsonPropertyAttribute

指示JsonSerializer始终使用指定的名称序列化成员

但是,我如何以编程方式指示JsonSerializer - 在我的情况下,在ReadJson方法中 - 使用给定的JsonPropertyAttribute?

http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonPropertyAttribute.htm

pet*_*ids 2

我认为这里的问题是由于 aNode包含属性Node形式的a ,解析变得递归ParentNode

在调用serializer.Populate(jObject.CreateReader(), node);序列化器时,将命中ParentNode类型的属性Node,然后它将尝试使用您的NodeJsonConverter. 那时,读者已经继续前进,你不再有 aStartObject但你有一个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;
}
Run Code Online (Sandbox Code Playgroud)