Home > Blockchain >  Newtonsoft.Json - Deserialize JSON to a custom JObject
Newtonsoft.Json - Deserialize JSON to a custom JObject

Time:06-16

I've got this structure from API.

[
  {
    "Id": 611932,
    "ProjectId": 6079,
    "Title": "Issue1"
    "Viewpoints": [
      {
        "Id": 885758,
        "IssueId": 611932,
        "Pinpoint": {
          "Position": {
            "X": -32.452857971191406,
            "Y": -14.971426010131836,
            "Z": 9.1110143661499023
          }
        }
      },
      {
        "Id": 885764,
        "IssueId": 611932,
        "Pinpoint": {
          "Position": {
            "X": -21.042057037353516,
            "Y": -21.742080688476563,
            "Z": 7.72857141494751
          }
        }
      }
    ]
  },
  {
    "Id": 611931,
    "ProjectId": 6079,
    "Title": "Issue2",
    "Viewpoints": [
      {
        "Id": 885757,
        "IssueId": 611931
      },
      {
        "Id": 885762,
        "IssueId": 611931,
        "Pinpoint": {
          "Position": {
            "X": -29.135581970214844,
            "Y": -14.971452713012695,
            "Z": 7.0672616958618164
          }
        }
      }
    ]
  },
  {
    "Id": 611930,
    "ProjectId": 6079,
    "Title": "Issue3",
    "Viewpoints": [
      {
        "Id": 885756,
        "IssueId": 611930,
      }
    ]
  }
]

I want to be able to construct a new structure containing all "Pinpoint" from all "Viewpoints" in form of objects so the resulting structure would look something like this (it doesn't have to be in an array it can also be contained as a new object):

[
  {
    "Id": 885758,
    "IssueId": 611932,
    "Pinpoint": {
      "Position": {
        "X": -32.452857971191406,
        "Y": -14.971426010131836,
        "Z": 9.1110143661499023
      }
    }
  },
  {
    "Id": 885764,
    "IssueId": 611932,
    "Pinpoint": {
      "Position": {
        "X": -21.042057037353516,
        "Y": -21.742080688476563,
        "Z": 7.72857141494751
      }
    }
  },
  {
    "Id": 885762,
    "IssueId": 611931,
    "Pinpoint": {
      "Position": {
        "X": -29.135581970214844,
        "Y": -14.971452713012695,
        "Z": 7.0672616958618164
      }
    }
  }
]

Note that I didn't include the "Viewpoint" array from Issue3 & one part of the "Viewpoint" array from issue2 because they didn't contain a "Pinpoint"...

Any ideas on how to achieve this? I've tried so far to add each "Position" object to the list only for testing purposes :

var jArray = JsonConvert.DeserializeObject<dynamic>(response.Content);

List<JToken> results = new List<JToken>();

foreach (JObject jObject in jArray)
{
    results.Add(new JObject(jObject["Viewpoints"].Children()["Pinpoint"]["Position"]));
}

However I get this error:

Can not add Newtonsoft.Json.Linq.JObject to Newtonsoft.Json.Linq.JObject.

CodePudding user response:

Working with System.Linq.

using System.Linq;

Solution 1

  1. Add range for JObject elements in jObject["Viewpoints"] array.
  2. With .Where() filter the JObject contains "Pinpoint" property.
foreach (JObject jObject in jArray)
{   
    results.AddRange(jObject["Viewpoints"].Children());
}
        
        
results = results
    .Where(x => x["Pinpoint"] != null)
    .ToList();

To get "Position" objects only:

results = results
    .Where(x => x["Pinpoint"] != null && x["Pinpoint"]["Position"] != null)
    .Select(x => x["Pinpoint"]["Position"])
    .ToList();

Solution 2

This solution works the same concept as Solution 1.

List<JToken> results = JArray.Parse(response.Content)
    .SelectMany(x => x["Viewpoints"])
    .Where(x => x["Pinpoint"] != null)
    .ToList();

To get "Position" objects only:

List<JToken> results = JArray.Parse(json)
    .SelectMany(x => x["Viewpoints"])
    .Where(x => x["Pinpoint"] != null && x["Pinpoint"]["Position"] != null)
    .Select(x => x["Pinpoint"]["Position"])
    .ToList();

Sample .NET Fiddle

  • Related