Closed justinushermawan closed 3 years ago
Seems weird C# doesn't have a standard library to manipulate JSON data, only serialize, deserialize from static types, or read only an arbitrary json document. Really need to be able to read, query and to manipulate JsonDocument, add elements, remove elements, etc and then turn it back to a string. The simple pain of getting any arbitrary piece of json and adding an extra element to it is astonishing. Think you guys need to implement a library that allows full manipulation of JSON data, not just a means to and end for deserializing/serializing static types.
in .NET there are 2 standards: 3rd party Nuget package Json.NET and .NET Core’s built-in classes System.Text.JSON
which are very fast but a bit limited compared to Json.NET.
here is an example of manipulating a JSON file without deserializing with the built in Json classes:
using var json = File.OpenRead (jsonPath);
using JsonDocument document = JsonDocument.Parse (json);
var options = new JsonWriterOptions { Indented = true };
using (var outputStream = File.Create ("NewFile.json"))
using (var writer = new Utf8JsonWriter (outputStream, options))
{
writer.WriteStartArray();
foreach (var person in document.RootElement.EnumerateArray())
{
int friendCount = person.GetProperty ("Friends").GetArrayLength();
if (friendCount >= 2)
person.WriteTo (writer);
}
}
(from: C# 8.0 in a Nutshell)
As promised, the PR providing a dynamic implementation sample is at #42097.
@steveharter - I'm unable to get your PR Code sample for supporting dynamic objects #42097 to load consistently - most of the time it won't load.
I also noticed that the example is missing a ToString()
implementation override on JsonDynamicString
- was this intentional? I'm planning on adding the override but don't want to rely on it if the final implementation in 6.0 won't use it.
Am I the only one who want a JSON POCO Object in C# (eg. JToken
) , so we can manipulate the "object
" easily and also other Json library can directly handle it too.
and @rs38 you solution is about write, and a mutable JSON DOM is about change and read (or write)
// do some change to the original JSON
var jobj = xxxx.Parse(Request.Body) as JObject;
if(ShouldInjectClaim == true)
{
jobj.Add("Claims", JArray.Parse(new []{ "claim1". "claim2" }));
}
// handle the "data"
DoSomething(jobj); // mostly read again
@John0King I don't think you're the only person, that's part of what this issue is about. Have you seen https://github.com/dotnet/designs/pull/163?
@udlose not sure why GitHub is having trouble loading the PR. You can always check out the commit: https://github.com/dotnet/runtime/commit/095539fd800775fc9542a07f411cbc1b7e72084e or even just browse to these tests that are now part of the product.
I also noticed that the example is missing a ToString() implementation override on JsonDynamicString - was this intentional?
I think that's just because the sample was minimal. I see @steveharter mentions this in the design doc: https://github.com/dotnet/designs/pull/163/files#diff-34fc37119c1d4491b844207aeed3a9c846c3e2d835fd712e164b1e47b89687c0R77
Closing; the JsonNode
feature is in main and will be in Preview 4.
Preview 5 will also add some new capabilities for JsonObject
including deterministic property ordering and being able to use JsonObject
as an "extension property" via [JsonExtensionDataAttribute
]. These are mentioned in the PR description.
@steveharter , @ericstj I pulled Steve's code sample for supporting dynamic
from https://github.com/dotnet/runtime/commit/095539fd800775fc9542a07f411cbc1b7e72084e. It worked fine when I was running under .NET Core 3.1. I'm upgrading the app to .NET 5 and getting an error:
JsonSerializerExtensions.JsonDynamicType.Value is inaccessible due to its protection level
I can easily change these from internal
to public
but I'm concerned about why it broke when migrating to .NET 5. Is there a new version of the code sample that works for .NET 5?
It looks to me like a compiler error around a identifier resolution, where something in another assembly is resolving to that Value member when it didn't before. It could be something unrelated to the update. If you have an issue to report (even against sample code) it's better to open a new issue and provide us with full details and a repro, that way we can better reproduce and diagnose what you are seeing.
Also, if you're willing to grab a nightly build you can try the official feature which is in as of last week: https://dev.azure.com/dnceng/public/_packaging?_a=package&feed=dotnet6&package=System.Text.Json&protocolType=NuGet&version=6.0.0-preview.5.21229.9
Thanks!
You can also try this
var obj = JsonDocument.Parse(Convert.ToString(your_dynamic_object));
var propertyVal = obj.RootElement.GetProperty("Your_Property_Name").GetString();
For those still interested in dynamic how valuable is that now that we have a writable DOM with JsonNode
?
Please add your comments to this issue: https://github.com/dotnet/runtime/issues/53195
Does
JsonSerializer.Parse(String, Type, JsonSerializerOptions)
support for dynamicExpandoObject
return type?Something like this:
dynamic p = JsonSerializer.Parse(json, typeof(ExpandoObject));