0

Having this JSON structure :

[
  {
    "Id": 885758,
    "IssueId": 611932,
    "Pinpoint": {
      "Name": null,
      "Position": {
        "X": -32.452857971191406,
        "Y": -14.971426010131836,
        "Z": 9.111014366149902
      },
      "Element1": null,
      "Element2": null
    }
  },
  {
    "Id": 885764,
    "IssueId": 611932,
    "Pinpoint": {
      "Name": null,
      "Position": {
        "X": -21.042057037353516,
        "Y": -21.742080688476562,
        "Z": 7.72857141494751
      },
      "Element1": null,
      "Element2": null
    },
  },
  {
    "Id": 885765,
    "IssueId": 611932,
    "Pinpoint": null
  }
]

I want to be able to obtain a List of JToken containing all Pinpoints that are not null So basically something like this :

  {
    "Pinpoint": {
      "Name": null,
      "Position": {
        "X": -32.452857971191406,
        "Y": -14.971426010131836,
        "Z": 9.111014366149902
      },
      "Element1": null,
      "Element2": null
    }
  },
  {
    "Pinpoint": {
      "Name": null,
      "Position": {
        "X": -21.042057037353516,
        "Y": -21.742080688476562,
        "Z": 7.72857141494751
      },
      "Element1": null,
      "Element2": null
    }
  }

Image here of what a normal LINQ select without the where condition returns : enter image description here

This is what I tried so far with related errors / exceptions :

//Cannot access child value on Newtonsoft.Json.Linq.JValue
List<JToken> results = JArray.Parse(response.Content)
    .Select(x => x["Pinpoint"])
    .Where(x => x["Pinpoint"] != null)
    .ToList();

//Object reference not set to an instance of an object.
List<JToken> results = JArray.Parse(response.Content)
    .Select(x => x["Pinpoint"])
    .Where(x => x["Pinpoint"].HasValues)
    .ToList();

//Object reference not set to an instance of an object.
List<JToken> results = JArray.Parse(response.Content)
    .Select(x => x["Pinpoint"])
    .Where(x => x["Pinpoint"].Type != JTokenType.Null)
    .ToList();
7
  • Does Checking for empty or null JToken in a JObject answer your question? Commented Jun 16, 2022 at 15:45
  • Errors are shown in the last C# code block see the comments. And no unfortunately it doesn't answer my question I can't make it work. Commented Jun 16, 2022 at 15:47
  • 1
    You need to put your Where clauses before your Select clause. Once you've done .Select(x => x["Pinpoint"]) your current item will be the value of x["Pinpoint"] so you can't do x => x["Pinpoint"] != null subsequently. Or keep the Where clause first and do .Where(p => !p.IsNullOrEmpty()) next, where IsNullOrEmpty() is from the linked question Checking for empty or null JToken in a JObject. Commented Jun 16, 2022 at 15:52
  • 1
    Demo of using Brian Roger's JsonExtensions.IsNullOrEmpty(this JToken token) here: dotnetfiddle.net/INCWaq. Do you need a separate answer or is a duplicate OK? Commented Jun 16, 2022 at 16:01
  • 1
    A null JToken will be returned when the value isn't present at all in the JSON. A non-null JToken will be returned with type JTokenType.Null when the value was found in the JSON but the value itself was null. I.e. if you do x["Pinpoint"] then if your JSON object looks like {} you will get back null but if your JSON object looks like {"Pinpoint":null} you will get back a JValue with JTokenType.Null. So you must check for both. For details see Strange behavior in json.net: why is a null JToken replaced with a non-null value?. Commented Jun 16, 2022 at 16:12

1 Answer 1

1

try this

List<JObject> pinPoints = JArray.Parse(json).Where(p => (p["Pinpoint"] as JObject) != null)
.Select(p => (JObject)p["Pinpoint"]).ToList();

UPDATE

thanks to @dbc, there is a shorthand

JArray.Parse(json).Select(p => p["Pinpoint"]).OfType<JObject>().ToList();
Sign up to request clarification or add additional context in comments.

3 Comments

JArray.Parse(json).Select(p => p["Pinpoint"]).OfType<JObject>().ToList() would work also and avoid doing p["Pinpoint"] twice.
@dbc Thank you! It is really interesting syntax. I will certainly use it in the future.
I removed the cast from inside the Select(p => p["Pinpoint"]) because, if p["Pinpoint"] is a JValue with JTokenType.Null, it will throw an exception. OfType() will filter them (as well as the actual null values) out later.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.