Search code examples
c#jsonjson-deserializationmailchimp-api-v3.0

Deserialize merge-fields and interests that have different names in different MailChimp lists


When deserializing the following json response I manage to get the subscribers id, e-mail and status, which is easy as these names are always the same and are not dependent on the particular settings in a list. But how can I deserialize the merge-fields and the interests that do have different names in different lists?

{ "members": [ {
    "id": "f777bbffab8d1ceca8b757df63c47cb8",
    "email_address": "urist.mcvankab+1@freddiesjokes.co",
    "unique_email_id": "882e9bec19",
    "status": "subscribed",
    "merge_fields":{
        "FNAME": "",
        "LNAME": "" },
    "interests":{
        "9143cf3bd1": true,
        "3a2a927344": false,
        "f9c8f5f0ff": false,
        "f231b09abc": true,
        "bd6e66465f": false },
//And so on...

How can I change my classes to deserialize the response?

My Member Class

public class Member
{
    public string id { get; set; }
    public string email_address { get; set; }
    public string status { get; set; }
    //public List<MergeField> mergeFields { get; set; }
    //public List<Interests> interests { get; set; }
}

Where the MergeField refers to to my old MergeField class, where the fields were hardcoded

public class MergeField
{
    public string FNAME { get; set; }
    public string LNAME { get; set; }
    public string ADDRESS { get; set; }
    public string MERGE4 { get; set; }
}

But I would like to use the same two Mergefield(s) classes that I use to deserialize the json response when requesting a list's merge-fields.

public class MergeFields
{
    public List<Mergefield> merge_fields { get; set; }
    public string list_id { get; set; }
    public int total_items { get; set; }
}

public class Mergefield
{
    public string merge_id { get; set; }
    public string tag { get; set; }
    public string name { get; set; }
    public string list_id { get; set; }
}

I found this answer How do deserialize JSON with non-standard (and varying) property names, but I cannot figure out how to use it in my scenarío.


Solution

  • You can use Dictionary<string, object> type for the merge fields and Dictionary<string, bool> type for the interests. Here's what your Member class should look like

    public class Member
    {
        public string id { get; set; }
        public string email_address { get; set; }
        public string status { get; set; }
        public Dictionary<string, object> merge_fields { get; set; }
        public Dictionary<string, bool> interests { get; set; }
    }
    

    Assuming you're using MemberResponse class for the response like below

    public class MemberResponse
    {
        public List<Member> members { get; set; }
        public string list_id { get; set; }
        public int total_items { get; set; }
    }
    

    Here's how you get the value for each merge field and interest

    MemberResponse memberResponse = .... // your code that calls the API
    
    // enumerate members
    foreach (var member in memberResponse.members)
    {
        // enumerate merge fields
        foreach (var key in member.merge_fields.Keys)
        {
            // when key = "FNAME", value would be the first name of the member
            // when key = "LNAME", value would be the last name of the member
            string value = member.merge_fields[key].ToString();
        }
    
        // enumerate interests
        foreach (var key in member.interests.Keys)
        {
            // when key = "9143cf3bd1", value would be true
            // when key = "3a2a927344", value would be false
            // ... and so on
            bool value = member.interests[key];
        }
    
    }
    

    Unfortunately there's no way to get the name and merge_id of the merge fields using the /lists/{list_id}/members endpoint since the response body only contains the tag of the merge fields, i.e FNAME, LNAME, etc. You'll need to make a separate call to /lists/{list_id}/merge-fields endpoint and compare the tag of each merge field in order to get the related name and merge_id.