Using JsonPath with System.Text.Json to query JSON in .NET

 
 
  • Gérald Barré

When you need to extract values from complex JSON payloads, manual navigation quickly becomes hard to read and maintain. Meziantou.Framework.JsonPath provides a JSONPath implementation for System.Text.Json based on RFC 9535, so you can query JSON documents using concise, standard expressions.

#Installation

Install the package from NuGet:

Shell
dotnet add package Meziantou.Framework.JsonPath

#Parse and evaluate a JSONPath expression

The package lets you parse an expression once and evaluate it against one or many documents.

C#
using System.Text.Json.Nodes;
using Meziantou.Framework;

var document = JsonNode.Parse("""
{
    "store": {
        "book": [
            { "title": "A", "price": 8.95 },
            { "title": "B", "price": 12.99 }
        ]
    }
}
""");

var path = JsonPath.Parse("$.store.book[*].title");
var matches = path.Evaluate(document);

foreach (var match in matches)
{
    Console.WriteLine($"{match.Path}: {match.Value}");
}

Each result includes:

  • The normalized path of the match (for example $['store']['book'][0]['title'])
  • The corresponding JSON value

#Evaluation modes: lax vs strict

Evaluate and EvaluateValue support two modes:

  • JsonPathEvaluationMode.Lax (default): invalid path operations return no match
  • JsonPathEvaluationMode.Strict: invalid path operations throw JsonPathEvaluationException
C#
var doc = JsonNode.Parse("""{"a": 1}""");
var path = JsonPath.Parse("$.name");

var laxValue = path.EvaluateValue(doc, JsonPathEvaluationMode.Lax);
// laxValue is null

var strictValue = path.EvaluateValue(doc, JsonPathEvaluationMode.Strict);
// throws JsonPathEvaluationException

Use lax mode when the JSON structure is optional or inconsistent. Use strict mode when missing fields should fail fast.

#Supported JSONPath features

Meziantou.Framework.JsonPath targets full RFC 9535 support, including:

  • Selectors: property name, wildcard, index, slice, and filter selectors
  • Child and descendant segments
  • Filter expressions with comparisons and logical operators
  • Built-in functions such as length(), count(), match(), search(), and value()
  • Normalized output paths

This means you can use one JSONPath syntax across tools and services that follow the standard.

#Additional resources

Do you have a question or a suggestion about this post? Contact me!

Follow me:
Enjoy this blog?