Home > OS >  Item[String] on System.Text.Json.Nodes.JsonNode: The node must be of type 'JsonObject'
Item[String] on System.Text.Json.Nodes.JsonNode: The node must be of type 'JsonObject'

Time:11-01

Experimenting with System.Text.Json, and not able to cleanly express chain of properties with optional early temination.

I want something like this

((JsonNode)node)?["a"]?["b"]?["c"]

Note, I'm not looking for workarounds (I can write some wrappers, extensions methods, etc). I want to understand if this my issue, doc issue, or framework bug.

Sample code:

            JsonNode rootNode = JsonNode.Parse(@"{""p"": ""v""}");

            // These work as expected
            _ = rootNode["a"]; // Ok
            // _ = rootNode["a"]["b"]; // System.NullReferenceException - expected
            _ = rootNode["a"]?["b"]; // Ok - expected
            _ = rootNode["p"]; // Ok - expected

            // Now this does not work as expected

            // Unexpected exception: The node must be of type 'JsonObject'
            //_ = rootNode["p"]?["x"];

            JsonNode p = rootNode["p"]; // Ok so far, p is not null

            // Unexpected exception: The node must be of type 'JsonObject'
            // How come? Doc says Item[String] Gets or sets the element with the specified property name. If the property is not found, null is returned.
            JsonNode x = p["x"]; 

Exception:

System.InvalidOperationException
  HResult=0x80131509
  Message=The node must be of type 'JsonObject'.
  Source=System.Text.Json
  StackTrace:
   at System.Text.Json.Nodes.JsonNode.AsObject()
   at System.Text.Json.Nodes.JsonNode.get_Item(String propertyName)
   at JTokenConditional.Program.Main(String[] args) in 

Environment: .net 6, VS 2022

CodePudding user response:

Docs for the indexer you use state in the Exceptions section:

InvalidOperationException The current JsonNode is not a JsonObject

And it makes sense - you can only obtain a property of something than can have a properties in the first place - that is of JsonObject (any other subtype of JsonNode cannot have properties). However, you have a JsonValue here (string "v"), so trying to obtain a property of that throws exception as it should according to the docs. It would only return null if you try to obtain non-existing property of JsonObject.

So if you are going this route - you have to first check if JsonNode you have is actually JsonObject before trying to access an indexer, if you don't want a possibility of exception.

  • Related