How to Serialize a Dictionary as Part of Its Parent Object Using JSON.Net

How to serialize a Dictionary as part of its parent object using Json.Net

If you're using Json.Net 5.0.5 or later and you're willing to change the type of your dictionary from Dictionary<string, string> to Dictionary<string, object>, then one easy way to accomplish what you want is to add the [JsonExtensionData] attribute to your dictionary property like this:

public class Test
{
public string X { get; set; }

[JsonExtensionData]
public Dictionary<string, object> Y { get; set; }
}

The keys and values of the marked dictionary will then be serialized as part of the parent object. The bonus is that it works on deserialization as well: any properties in the JSON that do not match to members of the class will be placed into the dictionary.

Deserialize and serialize a dictionary string, object using JSON.NET

The problem was that Json.Net has no way of knowing that an string, object deserialied and serialized again should be of a specific type. Luckily, there is an attribute called TypeNameHandling that tells Json.Net to save the type in the json string. Using this option for serializing and deserilizing worked perfectly :-).

JSON.NET serializing list as properties of parent object

Try change the WriteJson method to look like this:

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null || !(value is ParentObject))
return;

var pObject = (ParentObject) value;

writer.WriteStartObject();

writer.WritePropertyName("Prop1");
writer.WriteValue(pObject.Prop1);
writer.WritePropertyName("Prop2");
writer.WriteValue(pObject.Prop2);

foreach (var info in pObject.AdditionalInformation)
{
JObject jObj = JObject.FromObject(info);
foreach (var property in jObj.Properties())
{
writer.WritePropertyName(property.Name);
writer.WriteValue(property.Value);
}
}

writer.WriteEndObject();
}

But as you said, be careful when having more than one object from same type in the collection. It will generate multiple properties with same property names in the json string and you'll have problems during deserialization.

JSON.NET Serialize dictionary without property name

If you are willing to convert the dictionary to Dictionary<string, object> you can use [JsonExtensionData] attribute

public class MyClass
{
public string A { get; set; }

public string B { get; set; }

[JsonExtensionData]
public Dictionary<string, object> CS { get; set; }
}

Newtonsoft Json Serialisation of a Dictionary with custom properties

You can use the JsonExtensionDataAttribute that JSON.Net provides to put any properties that don't exist on the parent object in to the collection property.

Here's an example taken from another SO post.

JSON:

{
"X" : "value",
"key1": "value1",
"key2": "value2"
}

C# Data Object:

public class Test
{
public string X { get; set; }

[JsonExtensionData]
public Dictionary<string, object> Y { get; set; }
}

Key1 and Key2 will end up in the Dictionary because they don't exist in the class "Test, where as X will end up in the X property.

It's not perfect, it seems you have to have a Dictionary of type Dictionary, but it still might be a better option that using a custom serializer?

Here's an example on DotNetFiddle using one level of your data classes.

For the data:

public class UserData
{
public string UserName;
public string UserPhone;
}

public class CustomerData
{
public string CustomerName;

[JsonExtensionData]
public Dictionary<string, object> Users;
}

var data = new CustomerData()
{
CustomerName = "Foo",
Users = new Dictionary<string, object>()
{
{ "1", new UserData() { UserName = "Fireman", UserPhone = "0118 999 881 999 119 725 ... 3" } },
{ "2", new UserData() { UserName = "Jenny", UserPhone = "867-5309" } }
}
};

It produces the JSON:

{
"customerName": "Foo",
"1": {
"userName": "Fireman",
"userPhone": "0118 999 881 999 119 725 ... 3"
},
"2": {
"userName": "Jenny",
"userPhone": "867-5309"
}
}

Serialize class that inherits dictionary is not serializing properties

From Json.Net documentation:
"Note that only the dictionary name/values will be written to the JSON object when serializing, and properties on the JSON object will be added to the dictionary's name/values when deserializing. Additional members on the .NET dictionary are ignored during serialization."

Taken from this link: http://www.newtonsoft.com/json/help/html/SerializationGuide.htm

Assuming you want the keys & values of the dictionary on the same hierarchy level as PersonId in the json output, you can use the JsonExtensionData attribute with composition instead of inheritance, like this:

public class Maintenance
{
public int PersonId { get; set; }

[JsonExtensionData]
public Dictionary<string, dynamic> ThisNameWillNotBeInTheJson { get; set; }
}

Also look at this question: How to serialize a Dictionary as part of its parent object using Json.Net



Related Topics



Leave a reply



Submit