3

I'm trying to use the new System Text Json Library to read a single object from my json array. My json looks like this:

[
  {
    "Id": "test1",
    "Version": "16.0.461",
  },
  {
    "Id": "test2",
    "Version": "2.1.0",
  }
]

This is just an example. One Json Object actually has around 12 propteries. But suppose there is an class in c#, which looks like this:

     public class Data
     {
            public string Id { set; get; }
            public string Version { set; get; }
     }

and I'd like to just get the package where the id matches the given namen, which I tried like this:

    private static ObjectData GetSingleData(string jsonString, string objectName)
    {
                var options = new JsonDocumentOptions
                {
                    AllowTrailingCommas = true
                };

                using (JsonDocument document = JsonDocument.Parse(jsonString, options))
                {
                    ArrayEnumerator arrayEnumerator = document.RootElement.EnumerateArray();
                    //ObjectEnumerator objectEnumerator1 = document.RootElement.EnumerateObject();
                    while (arrayEnumerator.MoveNext())
                    {
                        JsonElement current = arrayEnumerator.Current;
                        if (objectName.Equals(current.GetProperty("id"))) 
                        {
                            //here the conversion from current to object should happen, but I don't know how                      
                        }
                    }
                }

                return null;
     }

is there a possiblity to convert a JsonElement to a instance of my Data Class?

madibat
  • 101
  • 2
  • 10
  • Have you tried deserializing instead of trying to access the elements one by one? Eg `JsonSerializer.Deserialize(json,options);` – Panagiotis Kanavos Oct 15 '19 at 09:07
  • This does work, but I thought I could deserialize just until the point, where I find the correct element instead of deserializing my whole jsonstring. – madibat Oct 15 '19 at 09:16
  • `JsonDocument.Parse` parses the entire document too. – Panagiotis Kanavos Oct 15 '19 at 09:28
  • Is there a possiblity to circumevent this? – madibat Oct 15 '19 at 09:31
  • You can use Utf8JsonReader to read elements one by one, but that works with UTF8 sequences in the form of `ReadOnlySpan` and `byte[]`. You'll have to use `varbytes=Encoding.UTF8.GetBytes(json);`, or read directly from a UTF8 JSON file. What are you trying to do in the first place? System.Text.Json isn't a general-purpose JSON parser yet, it's meant for Web app serialization, where the payload *is* UTF8 and has to be parsed/deserialized entirely before it gets consumed. – Panagiotis Kanavos Oct 15 '19 at 09:40
  • What I'm trying to do is to circumvent parsing the whole array if I just need one single object at the beginning of the array. But it seems like this is not really possible, or I don't really understand how to approach this. – madibat Oct 15 '19 at 09:59
  • No. Note parsing is pretty fast its generating the many parsing objects for further querying that's costly .. https://stu.dev/a-look-at-jsondocument/ has some more info. – user1496062 Nov 14 '19 at 00:57
  • Does this answer your question? [System.Text.Json.JsonElement ToObject workaround](https://stackoverflow.com/questions/58138793/system-text-json-jsonelement-toobject-workaround) – Mikael Dúi Bolinder Jan 15 '22 at 01:19

2 Answers2

1

Use something like this:

JsonElement current = document.RootElement;  
if (objectName.Equals(current.GetProperty("Id"))) 
{
     //But i'm using TryGetProperty
     //This is example code for first element in JSON array
     string id = current[0].GetProperty("Id").GetString(); //test1
     string version = current[0].GetProperty("Version").GetString(); //16.0.461
     
     //And now you can create your Data object
     Data data_object = new Data(id, version)
}

If I understand you correctly this should work.

UPD: I don't recommend that you use the standard library, so use Json.NET instead , this library is very convenient and works faster (for example, I achieved deserialization speed to ~0.2 seconds link for more info)

UPD 2:
For .NET 5:

Nik4ant
  • 11
  • 2
  • 3
0

.NET 6 has JsonElement.Deserialize<T>(). (source)

var obj = current.Deserialize<ObjectData>();
Mikael Dúi Bolinder
  • 2,080
  • 2
  • 19
  • 44