-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Additional JsonNode functionality #56592
Comments
Tagging subscribers to this area: @eiriktsarpalis, @layomia Issue DetailsBackground and motivationAdd missing features that were requested by the community. Note that API Proposalnamespace System.Text.Json.Nodes
{
public abstract class JsonNode
{
// Expensive; does a serialize and deserialize.
+ public JsonNode DeepClone()
// Expensive; made `static` for easier `null` comparison
+ public static JsonNode DeepEquals(JsonNode? node1, JsonNode? node2);
// Falls back to JsonElement.ValueKind when possible, otherwise calculates. Expensive in some cases.
+ public JsonValueKind GetValueKind(JsonSerializerOptions options = null)
// Returns JsonPath-compatible property name ("$", ".MyProperty", "[1]")
// Based on existing GetPath()
+ public string GetAccessorNameFromPath();
// Returns property name from parent object. Parent must be JsonObject otherwise InvalidOperationException.
+ public string GetPropertyName();
// Returns index from parent array. Parent must be JsonArray otherwise InvalidOperationException.
+ public int GetPropertyIndex();
}
public class JsonArray
{
// For homogeneous arrays, returns enumerator that wraps call GetValue<T>().
+ IEnumerable<T> GetValues<T>();
}
} API UsageDeepClone and DeepEquals JsonNode node = JsonNode.Parse("{\"Prop\":{\"NestedProp\":42}}");
JsonNode other = node.DeepClone();
bool same = JsonNode.DeepEquals(node, other); // true GetValueKind JsonNode node = JsonNode.Parse("42");
// In read-mode this is efficient:
JsonValueKind kind = node.ValueKind; // JsonValueKind.Number
// In edit-mode not sure efficient
node = new JsonValue(43);
kind = node.ValueKind; // JsonValueKind.Number
// And may internally perform serialization if not known
node = new JsonValue(new Dictionary<string, int>());
kind = node.ValueKind; // JsonValueKind.Object // Dictionaries are written as JSON objects (work in progress; todo) RisksNo response
|
|
I'd probably call this @steveharter not sure I understand how |
Yep thanks.
It returns just the immediate parent's property name \ index. So given "$.Order.Customer.Address", calling that method on Address instance returns ".Customer" |
There are basically two scenarios for the accessor name as I see it:
|
These APIs are not blocking as there are workarounds as shown in #55827, so they don't meet the bar for v6 this late in the release. |
@steveharter I am currently rewriting JsonNodes to a different structure. It would be great if there was a Replace on JsonArray and JsonObject that does not require to remove the parent first. |
Thanks. I added Replace() semantics to JsonNode to the proposal. The reason why |
Noting another popular request for consideration, to merge two JSON objects, e.g. https://www.newtonsoft.com/json/help/html/MergeJson.htm. cc @sebastienros who is interested in this. |
@steveharter saw your reply just now (Github Notification overload). Thanks a lot! |
Feedback from #55827
|
Feedback from #31433
|
I'm here to upvote the |
namespace System.Text.Json.Nodes
{
public partial class JsonNode
{
public JsonNode DeepClone();
public static bool DeepEquals(JsonNode? node1, JsonNode? node2);
public JsonValueKind GetValueKind(JsonSerializerOptions options = null);
public string GetPropertyName();
public int GetElementIndex();
public void ReplaceWith<T>(T value);
}
public partial class JsonArray
{
public IEnumerable<T> GetValues<T>();
}
} |
Per the API review discussion, I looked at Basically, the algorithm would look like this: public JsonValueKind GetValueKind()
{
if (this is JsonElement element) return element.ValueKind;
else if (TryGetKindFromKnownTypes(this, out kind)) return kind;
else return JsonValueKind.Unknown;
} I believe |
node = new JsonValue(43);
kind = node.ValueKind; // JsonValueKind.Undefined; there could be a custom converter for in32 writing it as a JSON object Doesn't seem to match the description: // In read mode, simply uses JsonElement.ValueKind.
// In edit mode for values wrapping a non-node value that is not a known type (string, int, long, etc) then
// JsonValueKind.Undefined is returned implying that to return the actual ValueKind one would serialize to a
// JsonElement\JsonNode along with any possible custom converter.
public JsonValueKind GetValueKind() Or is That would be very unfortunate IMO. I understand that it could be something else when serialized, but at this point it's not serialized, and as a user I would definitely like it to return |
Based on @steveharter's latest comment I believe that description is out of date. The current iteration would always return
In that case, couldn't it just be a property? |
Any status on adding json merge functionality? Was really hoping to have a simple way to merge on a key, and am frustrated the "upgrade" doesn't offer this. Specifically was hoping to be able to use Linq against the JsonDocument types, especially for left outer join type merges of data from separate API responses that you don't yet need defined types for, and so would prefer merging the JSON directly. |
@eiriktsarpalis You closed #31433 in favor of this issue, but merge functionality doesn't seem to have been addressed. Please reopen #31433 to ensure this critical functionality is not neglected. I think the community has been very vocal about the need for a simple and intuitive merge/union API. The VERY LAST comment by @davidhmays from back in May was quite eloquent and clear on this matter and his sentiments are echoed throughout this and many other issues. In fact, many of your own Feedback from XXX comments specifically mention this feature request. Its quite infuriating when after so much time has passed, both this issue and #31433 are now closed without any indication this will be addressed in the future. |
@goldsam I've reopened the issue, the particular API seems to have fallen through the cracks. |
Background and motivation
Add missing features that were requested by the community. Note that
System.Text.Json.Nodes.JsonNode
and derived types are new, added in 6.0 preview 4.API Proposal
API Usage
DeepClone and DeepEquals
GetValueKind
JsonArray.GetValues
The text was updated successfully, but these errors were encountered: