1

I'm porting a core 2.2 SDK to 3.0. Newtonsoft has been replaced by a native Json engine. My SDK takes a JObject and converts it to a concrete type using ToObject<T>()

Whats the equivalent of this with a JsonElement?

I want to deserialize a Message class whose Event property can only be determined at runtime :

private class Message
{
    public string Type { get; set; }
    public JsonElement Event { get; set; }
    public string[] GenericArguments { get; set; }
    public int? Id { get; set; }
}

In System.Text.Json I have to use this code to serialize the Event to JSON and then deserialize it again to the final type :

    private dynamic ParseTypeData(Message message)
    {
        Type type = typeFinder.GetEventType(message.Type);
        if (message.GenericArguments.Length > 0)
        {
            var genericArguments = message.GenericArguments
                .Select(typeFinder.GetType)
                .ToArray();

            type = type.MakeGenericType(genericArguments);
        }

        var json = message.Event.GetRawText();
        return JsonSerializer.Deserialize(json, type, Options);
    }

In JSON.NET the class was :

    private class Message
    {
        public string Type { get; set; }
        public JObject Event { get; set; }
        public string[] GenericArguments { get; set; }
        public int? Id { get; set; }
    }

And deserializing Event only needed :

return message.Event.ToObject(type);
dbc
  • 104,963
  • 20
  • 228
  • 340
Anders
  • 17,306
  • 10
  • 76
  • 144
  • You're asking how to deserialize a JSON element into an object. Why go through JsonElement? System.Text.Json is tailored focused on *very specific* scenarios around ASP.NET Core serialization. DOM parsing to JsonDocument, full deserialization using JsonSerializer or extremely-low-level not-quite-SAX with Utf8JsonReader. There's not even a *stream* JSon reader – Panagiotis Kanavos Oct 18 '19 at 09:10
  • I do not know the type until runtime, the dto looks like https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/blob/8a63fb1d78c722e8c47b38a035746da1821ea3ac/SignalR.EventAggregatorProxy.Client.DotNetCore/EventAggregation/EventProxy.cs#L166 and I deserlize like https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/blob/8a63fb1d78c722e8c47b38a035746da1821ea3ac/SignalR.EventAggregatorProxy.Client.DotNetCore/EventAggregation/EventProxy.cs#L90 – Anders Oct 19 '19 at 11:38
  • This was much more elegant in newtonsoft https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/blob/9c61efe49300823e56cf5949627a9460ffe6e7a0/SignalR.EventAggregatorProxy.Client.DotNetCore/EventAggregation/EventProxy.cs#L88 – Anders Oct 19 '19 at 11:38
  • you should post the code in the question itself, so people understand the context - you're using SignalR and have a message class whose payload can be any kind of object. What you as for is a utility method in Json.NET too - the string is parsed into a JObject *first* and then `ToObject` constructs and fills a custom object using reflection. System.Text.Json isn't that kind of parser *yet* - it doesn't have such utility methods, it's focused on fast parsing in the pipeline. Its job is to give you a `Message` quickly with minimal allocations – Panagiotis Kanavos Oct 21 '19 at 10:14
  • Perhaps you can write your own custom converter? That would be an option in JSON.NET too, to return the payload directly rather than going through a JObject. In JSON.NET this will probably halve the number of allocations – Panagiotis Kanavos Oct 21 '19 at 10:17
  • Any tips on how to use it without reinveting the wheel? I did have a quick look but I do not want to parse the json myself. – Anders Oct 21 '19 at 19:26
  • Why not use NewtonSoft.Json? Nothing stops you using it. It is not dprecated, just not really a good fit for some common Aspnet.Core workflows and thus replaced in these instances. But for your usecase (flexible deserialization) it is plainly trumps the advantage of speed . – Christian Sauer Oct 22 '19 at 07:55
  • @ChristianSauer even in JSON.NET, using a custom converter will reduce CPU/RAM in half. That's the quick solution but the cost is already significant, especially for an event aggregator library. – Panagiotis Kanavos Oct 22 '19 at 07:55
  • @ChristianSauer, its for a library. Newtonsoft was standard part of Core 2.2, its been replaced by System.Text.Json. DO not want to include none standard parts in a lib. – Anders Oct 22 '19 at 11:04
  • @PanagiotisKanavos I cant really see how I can use the System.Text.Json converter without doing all the conversion from scratch. – Anders Oct 22 '19 at 11:06
  • 1
    Related or duplicate: [System.Text.Json.JsonElement ToObject workaround](https://stackoverflow.com/q/58138793/3744182). – dbc Nov 26 '19 at 08:17

0 Answers0