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
How to Detect If I'm Running in Mono-Service
How to Correctly Implement a Backgroundworker with Progressbar Updates
Passing Properties by Reference in C#
Does C# Have Extension Properties
Convert String[] to Int[] in One Line of Code Using Linq
Difference Between Observablecollection and Bindinglist
Remove Items from One List in Another
Change a Web.Config Programmatically with C# (.Net)
Javascriptserializer.Deserialize - How to Change Field Names
Convert Integers to Written Numbers
How to Close a Login Form and Show the Main Form Without My Application Closing
Using Stored Procedure Output Parameters in C#
How to Merge Datagridview Cell in Winforms
Windows 10 Universal App File/Directory Access
Draw Semi Transparent Overlay Image All Over the Windows Form Having Some Controls