Skip to content

JsonObject should support property order manipulation #102932

@eiriktsarpalis

Description

@eiriktsarpalis

The JsonObject class implements IDictionary<string, JsonNode?>, however as of today the type does permit any manipulation of the order of its properties (even though order is being tracked internally). While this is consistent with the semantics of JSON where order of properties is not significant, it is often the case that one wants to arrange the order out of human readability concerns. For example, it is common for JSON schema docs to place the $schema and $id properties at the start of the object.

We should update JsonObject so that properties can be inserted at specific locations.

API Proposal

namespace System.Text.Json.Nodes;

public sealed partial class JsonObject : IDictionary<string, JsonNode?>
{
+    public int IndexOf(string key, out JsonNode? value);
+    public void Insert(int index, string key, JsonNode? value);
+    public void RemoveAt(int index);
}

API Usage

// Adds or moves the $id property to the start of the object
JsonObject schema = ...;
switch (schema.IndexOf("$id", out JsonNode? idValue))
{
    case < 0: // $id property missing
       idValue = (JsonNode)"https://example.com/schema";
       schema.Insert(0, "$id", idValue);
       break;

    case 0: // $id property already at the start of the object
        break; 

    case int index: // $id exists but not at the start of the object
        schema.RemoveAt(index);
        schema.Insert(0, "$id", idValue);
}

Alternative Designs

We can't have JsonObject implement IList<KeyValuePair<string, JsonNode?> (at least not without explicit implementation) since the base JsonNode class already exposes an indexer for ints with different signature and semantics.

Metadata

Metadata

Labels

api-approvedAPI was approved in API review, it can be implementedarea-System.Text.JsonblockingMarks issues that we want to fast track in order to unblock other important work

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions