0

Let's say I have the following complex object :

public class Customer
    {
        public List<Contact> Contacts { get; set; }
        public class Contact
        {
            public string Adresse { get; set; }
            public string Email { get; set; }
        }
    }

And I've got a Dictionary<string, string> with the following data :

enter image description here

How can I serialize this dictionary to have the following json string ? :

{
   "Contacts":[
      {
         "Adresse":"39 Dummy Street",
         "Email":"[email protected]"
      },
      {
         "Adresse":"455 Dummy Street",
         "Email":"[email protected]"
      },
      {
         "Adresse":"72 Dummy Street",
         "Email":"[email protected]"
      }
   ]
}
10
  • You will have to populate the Custommer object with the Contact instances from your dictionary. I don't understand your dictionary, however. Is the key of the dictionary actually "custommer.contacts[0].adresse", as a string? Do you intend to use reflection to discover that this string refers to the Adresse property? Commented Mar 23, 2020 at 12:42
  • My confusion comes from the fact that a Dictionary<string, string> cannot have a complex object as its key. It has a string. Commented Mar 23, 2020 at 12:44
  • Lasse V.Karlsen, custommer.contacts[0].adresse is the key and it is a string. Commented Mar 23, 2020 at 12:46
  • How about new Custommer { Contacts = dictionary.Values.Select(a => new Custommer.Contact { Adresse = a }).ToList() }; ? Commented Mar 23, 2020 at 12:51
  • To make the example simple, I just added one property "Adresse", but actually the object can be more complex. I updated the question adding the property "Email". Commented Mar 23, 2020 at 13:10

1 Answer 1

1

In order to do what you want, now that you've provided a more full question, you will need to do the following steps:

  1. For each key, extract the index number and the property name
  2. Then, make sure you have a Contact object inside the Contacts list, for the [index] index, according to the index you found in point 1
  3. Using the property name from the key, assign the value from the dictionary related to the key to the right property on the relevant Contact object

Here's a piece of code that will do this:

void Main()
{
    var dict = new Dictionary<string, string>
    {
        ["customer.contacts[0].adresse"] = "39 Dummy Street",
        ["customer.contacts[0].email"] = "[email protected]",
        ["customer.contacts[1].adresse"] = "455 Dummy Street",
        ["customer.contacts[1].email"] = "[email protected]",
        ["customer.contacts[2].adresse"] = "72 Dummy Street",
        ["customer.contacts[2].email"] = "[email protected]",
    };

    var c = new Customer { Contacts = new List<Customer.Contact>() };
    var re = new Regex(@"^customer.contacts\[(?<idx>\d+)\]\.(?<prop>.*)$");
    foreach (var (key, value) in dict)
    {
        var ma = re.Match(key);
        if (!ma.Success)
            continue;

        int index = int.Parse(ma.Groups["idx"].Value);
        string prop = ma.Groups["prop"].Value;

        while (index >= c.Contacts.Count)
            c.Contacts.Add(new Customer.Contact());

        switch (prop)
        {
            case "adresse":
                c.Contacts[index].Adresse = value;
                break;
                
            case "email":
                c.Contacts[index].Email = value;
                break;
        }
    }
    
    Console.WriteLine(JsonConvert.SerializeObject(c, Newtonsoft.Json.Formatting.Indented));
}

public class Customer
{
    public List<Contact> Contacts { get; set; }
    public class Contact
    {
        public string Adresse { get; set; }
        public string Email { get; set; }
    }
}

You can see it in action here on dotnetfiddle.

The output of the above will be:

{
  "Contacts": [
    {
      "Adresse": "39 Dummy Street",
      "Email": "[email protected]"
    },
    {
      "Adresse": "455 Dummy Street",
      "Email": "[email protected]"
    },
    {
      "Adresse": "72 Dummy Street",
      "Email": "[email protected]"
    }
  ]
}

Be aware of the following:

  1. If your keys skip an index you will get empty Contact objects in the Contacts collection. There will be an instance there, but none of the properties have been set. Example, your dictionary has keys for [0], [1] and [3], but missing [2]. There will be a Contact object for [2], but it will have default property values.
  2. There is no error checking that you're setting all the properties on any of the Contact objects. For instance, it is enough that you have a "customer.contacts[2].xyz" to get a Contact object for index [2], but property name "xyz" won't match anything, and if you don't have any other mentions of [2], both Adresse and Email will be left empty.
Sign up to request clarification or add additional context in comments.

2 Comments

@marc_s sigh Can you please fix the screenshot in the question as well? + all the comments? You went through the trouble of fixing the question and my answer, but now the screenshot and comments tell a slightly different story.
No I cannot - I can neither "re-do" the screenshot (since I didn't do it in the first place), and I cannot edit comments, either

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.