Reputation: 651
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.
Upvotes: 0
Views: 1404
Reputation: 129827
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
Upvotes: 5