Psth
Psth

Reputation: 300

While deserializing a JSON to a C# object, how can I map dynamic field names?

I have an issue when trying to map a JSON response I get from an API into an appropriate object that I made. Following is the JSON example

{
    "Count": "1",
    "Data": {
        "EmployeeMstr": {
            "ledger": "GL",
            "faid": "_tag_"
        }
    }
}

I need to create and object so that i can deserialize the above Json. I can create an object and desiarilse using JsonConvert.DeserializeObject<ResponseObject>(jsonResponse). Where ResponseObject is the class I created like following.

public class ResponseObject 
    {
        public string Count { get; set; }
        public string NextUri { get; set; }
        public Data Data{ get; set; }        
    }
public class Data
    {
        public string EmployeeMstr { get; set; }
    }

But the issue with this is, the key name "EmployeeMstr" in the above Json can be anything depending upon which table it is coming from ( like "HrNewHire" ,"Payroll" etc). I don't want to create separate object for all seperated tables. So what could be the best approach so that I can use this class to serialize the JSON irrespective of what that table name is?

Upvotes: 0

Views: 1997

Answers (3)

Ryan Motal
Ryan Motal

Reputation: 372

just replace your Model to dynamic JsonConvert.DeserializeObject<dynamic>(jsonResponse)

Upvotes: 0

Anu Viswan
Anu Viswan

Reputation: 18155

You could use a Dictionary to store the key values where the Key names could change. For example,

public class Value
{
    public string ledger { get; set; }
    public string faid { get; set; }
}

public class ResponseObject 
{
    public string Count { get; set; }
    public Dictionary<string,Value> Data { get; set; }  // Change here
    public string NextUri { get; set; }
}

Sample Output

enter image description here

Upvotes: 2

svladimirrc
svladimirrc

Reputation: 234

You could implement a Json Converter:

This maps the variant properties to the property you want to set.

public class CustomFieldConverter : JsonConverter
{
    private readonly Dictionary<string, string> _propertyMappings = new Dictionary<string, string>
    {
        {"EmployeeMstr", "CustomProperty"},
        {"HrNewHire", "CustomProperty"},
        {"Payroll", "CustomProperty"}
    };

    public override bool CanWrite => false;

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType.GetTypeInfo().IsClass;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        object instance = Activator.CreateInstance(objectType);
        var props = objectType.GetTypeInfo().DeclaredProperties.ToList();

        JObject jo = JObject.Load(reader);
        foreach (JProperty jp in jo.Properties())
        {
            if (!_propertyMappings.TryGetValue(jp.Name, out var name))
                name = jp.Name;

            PropertyInfo prop = props.FirstOrDefault(pi =>
                pi.CanWrite && pi.GetCustomAttribute<JsonPropertyAttribute>().PropertyName == name);

            prop?.SetValue(instance, jp.Value.ToObject(prop.PropertyType, serializer));
        }

        return instance;
    }
}

You have to set the attribute in the Class where your custom property its.

[JsonConverter(typeof(CustomFieldConverter))]
public class Data

you can see a detailed example here:

https://www.jerriepelser.com/blog/deserialize-different-json-object-same-class/

You can use JObject as type of CustomProperty to allow to maps distinct json objects. But I think your code will remain something unintelligible.

Other way is to maps this property to a class with this structure:

public class CustomProperty
{
    [JsonProperty("TableName")]
    public string TableName{ get; set; }

    [JsonProperty("Data")]
    public Dictionary<string, object> Properties { get; set; }
}

An loads the properties in a dictionary with a JsonConverter

Upvotes: 0

Related Questions