Search code examples
c#jsonjsonserializer

C# how to serialize JSON array of objects and convert object name to property value


I have a JSON string which has an array of objects. I need to serialize into a .NET class and use the object name as a property value.


public class DocumentFieldMap
    
{
        
    [Key]
        
    [JsonPropertyName("letterCode")]
        
    public string DocumentCode { get; set; }
        
    [JsonPropertyName("letterFields")]
        
    public List<DocumentField> DocumentFields { get; set; }
    
}

    
public class DocumentField
    
{
        
    [Key]
        
    public string FieldName { get; set; }
        
    public string DataSource { get; set; }
        
    public string ReadOnly { get; set; }
    
}
[
  {
    "letterCode": "RR",
    "letterFields": {
      "Name": {
        "DataSource": "",
        "ReadOnly": "true"
      },
      "Signature": {
        "DataSource": "",
        "ReadOnly": "false"
      }
    }
  }
]

I want to serialize the letterFields object name (ex. Name) as the FieldName property and I cannot find a good example.


Solution

  • Probably the easiest way would be to transform it to another class which will contain Dictionary<string, ...> (convention for (de)serializing dictionaries as object is supported by some JSON libraries, especially two "main" ones in .NET - Newtonsoft's Json.NET and System.Text.Json). For example with anonymous types:

    var maps = new[]
    {
        new DocumentFieldMap
        {
            DocumentCode = "code",
            DocumentFields =
            [
    
                new DocumentField
                {
                    FieldName = "Name",
                    DataSource = "",
                    ReadOnly = "true"
                }
            ]
        }
    };
    
    var serialize = JsonSerializer.Serialize(maps.Select(m => new
    {
        letterCode = m.DocumentCode,
        letterFields = m.DocumentFields
            .ToDictionary(f => f.FieldName, 
                field => new { field.DataSource, field.ReadOnly }) 
    }));
    

    Demo @sharplab.io

    Note that ToDictionary will throw for duplicate names, so you might need to handle that in case if this is a possibility. Also if you want you can switch from anonymous types to special classes for serialization (DTOs).

    Another option would be creating custom converter for the type.