简体   繁体   中英

JSON.net deserializes a reference to null

I have a C# application centered around objects called ProductParts, one Part can contain one or more child ProductParts. However, a Part can also contain references to other Parts in an indirect manner.

class ProductPart
{
    List<ProductPart> ProductParts;
    ProductPart MaterialReference { get; set; }
    ProductPart ColorReference { get; set; }
    ProductPart ActiveStateReference { get; set; }
}

I use JSON.net to save/load these Parts. However, I noticed an issue with certain references.

Here's a slimmed down JSON file example to demonstrate my problem.

{
  "$id": "3",
  "Name": "ProductName",
  "ProductParts": {
    "$id": "5",
    "$values": [
      {
        "$id": "6",
        "Name": "top",
        "ProductParts": {
          "$id": "8",
          "Name": "bottom",
          "$values": [
            {
              "$id": "9",
              "MaterialReference": {
                "$ref": "6"
              },
              "ColorReference": {
                "$ref": "6"
              },
              "ActiveStateReference": {
                "$ref": "6"
              }
            }
          ]
        }
      }
    ]
  }
}

When I load a file like this into my application, the Reference fields are null. Is this because I've created an reference loop here? I tried to get JSON.net to throw an error in this case by using

ReferenceLoopHandling = ReferenceLoopHandling.Error

But to my surprise, that doesn't throw an error. Have I created a Datastructure that cannot be parsed?

You need to remove the circular reference in your class. Create a Mapping class structure like this to deserialize the Json

    class ProductPart
    {
        [JsonProperty("$id")]
        public int Id { get; set; }
        public string Name { get; set; }
        [JsonProperty("ProductParts")]
        List<ProductPartsA> ProductPartsA;
    }

    class ProductPartsA
    {
        [JsonProperty("$id")]
        public int Id { get; set; }
        public string Name { get; set; }
        [JsonProperty("ProductParts")]
        List<ProductPartsB> ProductPartsB;
    }

    class ProductPartsB
    {
        [JsonProperty("$id")]
        public int Id { get; set; }
        public string Name { get; set; }
        [JsonProperty("$values")]
        List<Values> Values;
    }

    class Values
    {
        [JsonProperty("$id")]
        public int Id { get; set; }
        public Reference MaterialReference { get; set; }
        public Reference ColorReference { get; set; }
        public Reference ActiveStateReference { get; set; }
    }

    class Reference
    {
        [JsonProperty("$ref")]
        public string Ref { get; set; }
    }

Obviously this can be handled a little nicer with inheritance but you get the idea. You can then deserialize your json by simply:

var myClass = JsonConvert.DeserializeObject<ProductPart>(jsonstr);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM