Bnaya.Extensions.Json 5.1.161

There is a newer version of this package available.
See the version list below for details.
dotnet add package Bnaya.Extensions.Json --version 5.1.161                
NuGet\Install-Package Bnaya.Extensions.Json -Version 5.1.161                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Bnaya.Extensions.Json" Version="5.1.161" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Bnaya.Extensions.Json --version 5.1.161                
#r "nuget: Bnaya.Extensions.Json, 5.1.161"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Bnaya.Extensions.Json as a Cake Addin
#addin nuget:?package=Bnaya.Extensions.Json&version=5.1.161

// Install Bnaya.Extensions.Json as a Cake Tool
#tool nuget:?package=Bnaya.Extensions.Json&version=5.1.161                

Bnaya Json Extensions

Build & Deploy NuGet

NuGet

codecov

Functionality of this library includes:


ToEnumerable

Enumerate over json elements.

Useful for fetching selected parts of the json

Path based enumeration

Rely on path convention:

json.ToEnumerable(/path convention/);

<details><summary>Json</summary> <blockquote>

{
  "friends": [
    {
      "name": "Yaron",    
      "id": 1
    },
    {
      "name": "Aviad",   
      "id": 2
    }
  ]
}

</blockquote> </details>

<details><summary>Sample: friends.[].name or friends.*.name</summary> <blockquote>

var items = source.ToEnumerable("friends.[].name");

OR

var items = source.ToEnumerable("friends.*.name");

RESULT

["Yaron", "Aviad"]

</blockquote> </details>

<details><summary>Sample: friends.[0].name</summary> <blockquote>

var items = source.ToEnumerable("friends.[0].name");

RESULT

["Yaron"]

</blockquote> </details>

<details><summary>Sample: friends.[0].*</summary> <blockquote>

var items = source.ToEnumerable("friends.[0].*");

RESULT

["Yaron",1]

</blockquote> </details>

See: YieldWhen_Path_Test in the source code

Predicate based enumeration

Yield element according to predicate and onMatch delegates.

Sample:

<details><summary>Json</summary> <blockquote>

{
    "projects": [ {
        "key": "cloud-d",
        "duration": 8
    }, {
    "users": [{
        "rank": {
            "job": 10,
            "relationship": {
                "projects": [
                    { "key": "cloud-d", "team": 5 },
                    { "key": "cloud-x", "team": 32 }
                ]
            }
        },
    }]
}

</blockquote> </details>

<details><summary>Code</summary> <blockquote>

TraverseInstruction Predicate(JsonElement current, IImmutableList<string> breadcrumbs)
{
    if (breadcrumbs.Count < 4)
        return ToChildren;

    if (breadcrumbs[^4] == "relationship" &&
        breadcrumbs[^3] == "projects" &&
        breadcrumbs[^1] == "key")
    {
        return new TraverseInstruction(Stop, TraverseAction.Take);
    }

    return ToChildren;
}
var items = source.ToEnumerable(Predicate);

</blockquote> </details>


Filter

Reduce (or modify) a json

<details><summary>Json</summary> <blockquote>

JSON:

{
  "A": 10,
  "B": [
    { "Val": 40 },
    { "Val": 20 },
    { "Factor": 20 }
  ],
  "C": [0, 25, 50, 100 ],
  "Note": "Re-shape json"
}

</blockquote> </details>

<details><summary>Code</summary> <blockquote>


TraverseInstruction Strategy(
                JsonElement e,
                IImmutableList<string> breadcrumbs)
{ 
    if (e.ValueKind == JsonValueKind.Number)
    {
        var val = e.GetInt32();
        if (val > 30)
            return TraverseInstruction.TakeOrReplace;
        return TraverseInstruction.SkipToSibling;
    }
    if (e.ValueKind == JsonValueKind.Array || e.ValueKind == JsonValueKind.Object)
        return TraverseInstruction.ToChildren;
    return TraverseInstruction.TakeOrReplace;
}

JsonElement target = source.Filter(Strategy);

Will result in:

{
  "B": [ { "Val": 40 }],
  "C": [ 50, 100 ],
  "Note": "Re-shape json"
}

</blockquote> </details>


Keep

Path based Filter

<details><summary>Json</summary> <blockquote>

{
  "A": 10,
  "B": [
    { "Val": 40 },
    { "Val": 20 },
    { "Factor": 20 }
  ],
  "C": [0, 25, 50, 100 ],
  "Note": "Re-shape json"
}

</blockquote> </details>

<details><summary>Sample: B.*.val</summary> <blockquote>

var target = source.Keep("B.*.val");

RESULT

{"B":[{"Val":40},{"Val":20}]}

</blockquote> </details>

<details><summary>Sample: B.[]</summary> <blockquote>

var target = source.Keep("B.[]");

RESULT

{"B":[{"Val":40},{"Val":20},{"Factor":20}]}

</blockquote> </details>

<details><summary>Sample: B.[1].val</summary> <blockquote>

var target = source.Keep("B.[].Factor");

RESULT

{"B":[{"Factor":20}]}

</blockquote> </details>

<details><summary>Sample: B.[1].val</summary> <blockquote>

var target = source.Keep("B.[1].val");

RESULT

{"B":[{"Val":20}]}

</blockquote> </details>


Remove

Remove elements from the json.

<details><summary>Json</summary> <blockquote>

{
  "A": 10,
  "B": [
    { "Val": 40 },
    { "Val": 20 },
    { "Factor": 20 }
  ],
  "C": [0, 25, 50, 100 ],
  "Note": "Re-shape json"
}

</blockquote> </details>

<details><summary>Sample: B.[]</summary> <blockquote>

var target = source.Remove("B.[]");

RESULT

{"A":10,"C":[0,25,50,100],"Note":"Re-shape json"}

</blockquote> </details>

<details><summary>Sample: B.*.val</summary> <blockquote>

var target = source.Remove("B.*.val");

RESULT

{"A":10,"B":[{"Factor":20}],"C":[0,25,50,100],"Note":"Re-shape json"}

</blockquote> </details>

<details><summary>Sample: B.[1]</summary> <blockquote>

var target = source.Remove("B.[1]");

RESULT

{"A":10,"B":[{"Val":40},{"Factor":20}],"C":[0,25,50,100],"Note":"Re-shape json"}

</blockquote> </details>

<details><summary>Sample: B</summary> <blockquote>

var target = source.Remove("B");

RESULT

{"A":10,"C":[0,25,50,100],"Note":"Re-shape json"}

</blockquote> </details>

<details><summary>Sample: B.[1].val</summary> <blockquote>

var target = source.Remove("B.[1].val");

RESULT

{"A":10,"B":[{"Val":40},{"Val":20},{"Factor":20}],"C":[0,25,50,100],"Note":"Re-shape json"}

</blockquote> </details>


TryAddProperty

Try to add property if missing.

<details><summary>Sample 1</summary> <blockquote>

{ "A": 0, "B": 0 }
source.RootElement.TryAddProperty("C", 1);

Result in:

{ "A": 0, "B": 0, "C": 1 }

</blockquote> </details>

<details><summary>Sample 2</summary> <blockquote>

{ "A": 0, "B": 0, "C": 0 }
source.RootElement.TryAddProperty("C", 1);

Result in:

{ "A": 0, "B": 0, "C": 0 }

</blockquote> </details>

<details><summary>Sample: 3</summary> <blockquote>

{ "A": 0, "B": 0, "C": null }
var source = JsonDocument.Parse(json);
source.RootElement.TryAddProperty("C", 1);

Result in:

{ "A": 0, "B": 0, "C": 1 }

</blockquote> </details>

Unless sets the options not to ignore null

<details><summary>Sample: ignored null</summary> <blockquote>

Ignored null

var options = new JsonPropertyModificatonOpions
{
    IgnoreNull = false
};
var source = JsonDocument.Parse(json);
source.RootElement.TryAddProperty("C", 1);

Result in:

{ "A": 0, "B": 0, "C": null }

</blockquote> </details>

<details><summary>Sample: Changing property within a path</summary> <blockquote>

Changing property within a path

{
  "X": {
    "Y": {
    	"A": 0,
    	"B": 0
    }
  },
  "Y": { "Q": 2 }
}
source.RootElement.TryAddProperty("X.Y", "C", 1);

Result in:

{
  "X": {
      "Y": {
          "A": 0,
          "B": 0,  
          "C": 1
      }
  },
  "Y": { "Q": 2 }
}

</blockquote> </details>


TryGetValue

Try to get a value within a path

<details><summary>Json</summary> <blockquote>

{
  "B": {
    "B1": ["Very", "Cool"],
    "B2": {
        "B21": {
          "B211": "OK"
        },
        "B22": 22,   
        "B23": true,
        "B24": 1.8,
        "B25": "2007-09-01T10:35:01",
        "B26": "2007-09-01T10:35:01+02"
    }
  }
}

</blockquote> </details>

<details><summary>Sample: B.B1</summary> <blockquote>

source.TryGetValue(out JsonElement value, "B.B1")

Result in:

["Very","Cool"]

</blockquote> </details>

<details><summary>Sample: B.B1.*</summary> <blockquote>

source.TryGetValue(out JsonElement value, "B.B1.*")

Result in:

Very

</blockquote> </details>

TryGet...

Try to get a value within a path.

<details><summary>Json</summary> <blockquote>

{
  "B": {
    "B1": ["Very", "Cool"],
    "B2": {
        "B21": {
          "B211": "OK"
        },
        "B22": 22,   
        "B23": true,
        "B24": 1.8,
        "B25": "2007-09-01T10:35:01",
        "B26": "2007-09-01T10:35:01+02"
    }
  }
}

</blockquote> </details>

<details><summary>Sample: String</summary> <blockquote>

source.TryGetString(out JsonElement value, "B.B2.*.B211")

Result in: OK

</blockquote> </details>

<details><summary>Sample: DateTiemOffset</summary> <blockquote>

source.TryGetValue(out JsonElement value, "B.*.B26")

Result in: 2007-09-01T10:35:01+02

</blockquote> </details>

<details><summary>Sample: Double</summary> <blockquote>

source.TryGetNumber(out double value, "B.B2.B24")

Result in: 1.8

</blockquote> </details>


Merge

Merging 2 or more json. The last json will override previous on conflicts

<details><summary>Sample: 1</summary> <blockquote>

Source: { "A": 1 } , Merged: { "B": 2 }

var target = source.Merge(merged);

Result in: {"A":1,"b":2}

</blockquote> </details>

<details><summary>Sample: 2</summary> <blockquote>

Source: { "A": 1 } , Merged: {"B":2,"C":3}

var target = source.Merge(merged);

Result in: { "A":1, "B":2, "C":3 }

</blockquote> </details>

<details><summary>Sample: </summary> <blockquote>

Source: { "A": 1 } , Merged1: {"B":2} , Merged2: {"C":3}

var target = source.Merge(merged1, merged2);

Result in: { "A":1, "B":2, "C":3 }

</blockquote> </details>

<details><summary>Sample: </summary> <blockquote>

Source: { "A": 1 }

var target = source.MergeObject(new { b = 2 });

Result in: {"A":1, "B":2}

</blockquote> </details>

Merge Into

Merging json into specific path of a source json.

The last json will override any previous one in case of a conflicts

<details><summary>Sample: 1</summary> <blockquote>

Source

{ "A": 1, "B": { "B1":[1, 2, 3] }, "C": { "D": { "X":1, "Y":2 } } }
var target = source.MergeInto("C.D.X", 100);

Result in: { "A": 1, "B": { "B1":[1, 2, 3] }, "C": { "D": { "X":100, "Y":2 } } }

</blockquote> </details>

<details><summary>Sample: 2</summary> <blockquote>

Source

{ "A": 1, "B": { "B1":[1, 2, 3] }, "C": { "D": { "X":1, "Y":2 } } }

Merged

{ "Z": 3}
var target = source.MergeInto("C.D", merged);

Result in: { "A": 1, "B": { "B1":[1, 2, 3] }, "C": { "D": { "X":1, "Y":2, "Z": 3 } } }

</blockquote> </details>

<details><summary>Sample: 3</summary> <blockquote>

Source

{'A':1,'B': {'B1':1}}

Merged

{'B1':3, 'C':[1,2,3]}
var target = source.MergeInto("B", merged);

Result in: {'A':1, 'B':{'B1':3, 'C':[1,2,3]}}

</blockquote> </details>

<details><summary>Sample: 4</summary> <blockquote>

Source

{'A':1,'B':{'B1':[1,2,3]}}
var target = source.MergeInto("B.B1.[1]", 5);

Result in: {'A':1, 'B':{'B1':[1,5,3]}}

</blockquote> </details>

Serialization

ToJson

Convert .NET object into JsonElement.

var entity = new Entity(12, new BEntity("Z"));
JsonElement json = entity.ToJson();
var arr = new []{ 1, 2, 3 };
JsonElement json = arr.ToJson();

AsString

Convert JsonElement to string

JsonElement json = ...;
string compact = json.AsString();
string indented = json.AsIndentString();
string raw = json.GetRawText(); // same as json.AsIndentString();

ToStream

Convert JsonElement to stream

var json = JsonDocument.Parse(JSON);
var srm = json.ToStream() as MemoryStream;
string result = Encoding.UTF8.GetString(srm.ToArray()) ;

Looking for other extensions?

Check the following

Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on Bnaya.Extensions.Json:

Package Downloads
EventSourcing.Backbone.Abstractions

Package Description

EventSourcing.Backbone.Channels.S3StoreProvider.Common

Package Description

EventSourcing.Backbone.Channels.RedisProvider.Common

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
5.1.162 204 9/19/2023
5.1.161 357 9/14/2023
5.1.160 172 9/14/2023
5.1.159 14,980 5/17/2023
5.1.158 174 5/17/2023
5.1.156 163 5/17/2023
5.1.155 166 5/17/2023
5.1.154 164 5/17/2023
5.1.153 184 5/11/2023
5.1.152 180 5/11/2023
5.1.151 160 5/11/2023