Search code examples
c#json.net-coresystem.text.json.net-core-3.1

Deserialize anonymous type with System.Text.Json


I am updating some apps for .NET Core 3.x, and as part of that I'm trying to move from Json.NET to the new System.Text.Json classes. With Json.NET, I could deserialize an anonymous type like so:

var token = JsonConvert.DeserializeAnonymousType(jsonStr, new { token = "" }).token;

Is there an equivalent method in the new namespace?


Solution

  • As of .Net 5.0, deserialization of immutable types -- and thus anonymous types -- is supported by System.Text.Json. From How to use immutable types and non-public accessors with System.Text.Json:

    System.Text.Json can use a parameterized constructor, which makes it possible to deserialize an immutable class or struct. For a class, if the only constructor is a parameterized one, that constructor will be used.

    As anonymous types have exactly one constructor, they can now be deserialized successfully. To do so, define a helper method like so:

    public static partial class JsonSerializerExtensions
    {
        public static T? DeserializeAnonymousType<T>(string json, T anonymousTypeObject, JsonSerializerOptions? options = default)
            => JsonSerializer.Deserialize<T>(json, options);
    
        public static ValueTask<TValue?> DeserializeAnonymousTypeAsync<TValue>(Stream stream, TValue anonymousTypeObject, JsonSerializerOptions? options = default, CancellationToken cancellationToken = default)
            => JsonSerializer.DeserializeAsync<TValue>(stream, options, cancellationToken); // Method to deserialize from a stream added for completeness
    }
    

    And now you can do:

    var token = JsonSerializerExtensions.DeserializeAnonymousType(jsonStr, new { token = "" }).token;
    

    Demo fiddle here.