0

I have the following C# code:

using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

public class Program
{
    private static readonly JsonSerializerSettings prettyJson = new JsonSerializerSettings()
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver(),
        Formatting = Formatting.Indented
    };
    public class dialup {
        public Dictionary<string,uint> speeds;
        public string phonenumber;
    }
    public class Ethernet {
        public string speed;
    }
    public class ipv4 {
        public bool somecapability;
    }

    public class SiteData {
        public string SiteName;

        [JsonExtensionData]
        public Dictionary<string, object> ConnectionTypes;
    }
    public static void Main() 
    {   
        var data = new SiteData()
        {
            SiteName = "Foo",
            ConnectionTypes = new Dictionary<string, object>() 
            {
                { "1",  new dialup() { speeds=new Dictionary<string,uint>() {{"1",9600},{"2",115200}}, phonenumber = "0118 999 881 999 119 725 ... 3" } },
                { "2",  new Ethernet() { speed = "1000" } },
                {"3", new ipv4() { somecapability=true}}
            }
        };
        var json = JsonConvert.SerializeObject(data, prettyJson);   
        Console.WriteLine(json);
    }
}

This results in the following JSON:

{
  "siteName": "Foo",
  "1": {
    "speeds": {
      "1": 9600,
      "2": 115200
    },
    "phonenumber": "0118 999 881 999 119 725 ... 3"
  },
  "2": {
    "speed": "1000"
  },
  "3": {
    "somecapability": true
  }
}

What I need in the JSON is:

{
  "siteName": "Foo",
  "1": {
    "dialup":{
    "speeds": {
      "1": 9600,
      "2": 115200
    },
    "phonenumber": "0118 999 881 999 119 725 ... 3"
    }
  },
  "2": {
    "Ethernet":{
    "speed": "1000"
    }
  },
  "3": {
    "ipv4":{
    "somecapability": true
    }
  }
}

How can I do this using Json.NET? Json.NET deserializes this just fine, but I've been looking for days on how to make it serialize it the same way.

2
  • 1
    You need to add a property to store the type/name. Classes serialize to { } whereas properties (e.g speed) get the name serialized Commented Jun 16, 2016 at 23:08
  • But wouldn't that result in that property name being in the Json as well? Or do I use JsonProperty for that? I'm having a hard time visualizing how I'd accomplish this in code. Commented Jun 17, 2016 at 0:14

1 Answer 1

5

To accomplish this, you need to wrap each of the values in your ConnectionTypes dictionary in another dictionary. You can create a helper method to make this easier:

private static Dictionary<string, object> WrapInDictionary(object value) 
{
    return new Dictionary<string, object>()
    {
        { value.GetType().Name, value }
    };
}

Then you can initialize your data like this:

var data = new SiteData()
{
    SiteName = "Foo",
    ConnectionTypes = new Dictionary<string, object>() 
    {
        { "1", WrapInDictionary( new dialup() { Speeds = new Dictionary<string, uint>() { {"1", 9600}, {"2", 115200} }, PhoneNumber = "0118 999 881 999 119 725 ... 3" } ) },
        { "2", WrapInDictionary( new Ethernet() { Speed = "1000" } ) },
        { "3", WrapInDictionary( new ipv4() { SomeCapability=true } ) }
    }
};

Fiddle: https://dotnetfiddle.net/gGXlDo

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! If I could up vote this 1,000 times I would. Works great.
No problem; glad I could help.

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.