'C# Map Json Dictionary to nested class
I have a Dicionary with key values.
It can be dictionary or json string like below:
[
{
"Key": "UserName",
"Text": "Jack"
},
{
"Key": "UserAge",
"Text": 30
},
{
"Key": "Address",
"Text": "Address Location"
},
{
"Key": "Id",
"Text": 10
}
]
I want to map above json to class below:
public class Record
{
public User User { get; set; }
public Location Location { get; set; }
[Description("Id")]
[JsonProperty("Id")]
public int Id { get; set; }
}
public class User
{
[Description("UserName")]
[JsonProperty("UserName")]
public string Name { get; set; }
[Description("UserAge")]
[JsonProperty("UserAge")]
public int Age { get; set; }
}
public class Location
{
[Description("Address")]
[JsonProperty("Address")]
public string Address { get; set; }
}
I am able to define the attribute with Description or JsonProperty.
Is there any way to achieve this?
Solution 1:[1]
You can do this in 3 steps:
1. Read the data into a collection a records
First define the record type:
record PropertyNameAndValue([property:JsonProperty("Key")]string Name, [property: JsonProperty("Text")] object Value);
I've used the [property:JsonProperty(...)] annotations to be able to use arbitrary names for the record's properties.
Let's read the json
var propertyNameAndValues = JsonConvert.DeserializeObject<PropertyNameAndValue[]>(json);
2. Populate a flattened structure
Let's define a class with 4 properties:
class Model
{
public long Id { get; set; }
public string UserName { get; set; }
public long UserAge { get; set; }
public string Address { get; set; }
}
I've defined Id and UserAge as long instead of int since Json.NET will parse these numbers as System.Int64.
Let's populate with data
var model = new Model();
foreach (var property in propertyNameAndValues)
{
typeof(Model).GetProperty(property.Name).SetValue(model, property.Value);
}
3. Define an AutoMapper rule
Since I'm not using AutoMapper on a daily basis I can't show you right now you how the mapping rule should look like. Later this week I might have enough time to play with it a bit :D
UPDATE #1
Thanks for the suggestion for Lucian Bargaoanu here is the mapping:
var config = new MapperConfiguration(cfg =>
cfg.CreateMap<Record, Model>()
.ForMember(dest => dest.Address, opt => opt.MapFrom(src => src.Location.Address))
.ForMember(d => d.UserAge, opt => opt.MapFrom(src => src.User.Age))
.ForMember(d => d.UserName, opt => opt.MapFrom(src => src.User.Name))
.ReverseMap()
);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
