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

Custom deserialization with System.Text.Json - Grouping fields into object


Using System.Text.Json and .NET Core 3.1, how can I deserialize the following JSON for a membership:

{
    "id": 123,
    "firstName": "James",
    "lastName": "Smith",
    "group": "Premium"
    "state": "Active"
}

Classes:

public class Membership
{
    public Member Member { get; set; }
    public string Group { get; set; }
    public string State { get; set; }
}

and

public class Member
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Thanks!


Solution

  • Personally, I would create a POCO / Model to match the Json exactly as it is brought in and deserialize to that. Then add a constructor to your Membership class that accepts the incoming, deserialized json model and builds up your object as desired.

    It's an extra step in between getting the json and returning your own model, but since the source (incoming json) doesn't structurally match the destination (your poco object), translation has to happen somewhere. I find it easiest to follow the translation when there is this explicit separation in my code.

    Something like this:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text.Json;
    using System.Text.Json.Serialization;
    
    public class Program
    {
            // I wrapped in [] to make a list
            const string inJson = @"[{
                ""id"": 123,
                ""firstName"": ""James"",
                ""lastName"": ""Smith"",
                ""group"": ""Premium"",
                ""state"": ""Active""
            }]";
    
        public static void Main()
        {
            var deserialized = JsonSerializer.Deserialize<List<JsonMember>>(inJson);
            var asMembership = deserialized.Select(i => new Membership(i)).ToList();
            
            foreach(var m in asMembership){
                Console.WriteLine($"Group: {m.Group}");
                Console.WriteLine($"State: {m.State}");
                Console.WriteLine($"Member Id: {m.Member.Id}");
                Console.WriteLine($"Member First Name: {m.Member.FirstName}");
                Console.WriteLine($"Member Last Name: {m.Member.LastName}");
            }
        }
    }
    
    public class JsonMember{
        [JsonPropertyName("id")]
        public int Id { get; set; }
    
        [JsonPropertyName("firstName")]
        public string FirstName { get; set; }
    
        [JsonPropertyName("lastName")]
        public string LastName { get; set; }
    
        [JsonPropertyName("group")]
        public string Group { get; set; }
    
        [JsonPropertyName("state")]
        public string State { get; set; }
    }
    
    public class Membership
    {
        public Member Member { get; set; }
        public string Group { get; set; }
        public string State { get; set; }
        
        public Membership(JsonMember jsonMember){
            Group = jsonMember.Group;
            State = jsonMember.State;
            
            Member = new Member{
                Id = jsonMember.Id,
                FirstName = jsonMember.FirstName,
                LastName = jsonMember.LastName
            };
        }
    }
    
    public class Member
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
    

    output:

    Group: Premium

    Group: Active

    Member Id: 123

    Member First Name: James

    Member Last Name: Smith

    See: https://dotnetfiddle.net/y0i6Sx