Newtonsoft JSON serialize a template
<p>I am trying to serialize a class to a JSON string. First, my actual code:</p>

<pre><code>// Note that this class is inside a PCL
public class CommunicationMessage {

    public String Key { get; set; }

    public String Value { get; set; }

    public List&lt;CommunicationMessage&gt; Childs { get; set; }
}
</code></pre>

<p>This is a template which can be converted to xml which could look like this:</p>

<pre><code>&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
&lt;myproject&gt;
    &lt;communicationmessage&gt;
        &lt;header&gt;
             &lt;participantid&gt;1&lt;/participantid&gt;
             &lt;deviceid&gt;54325&lt;/deviceid&gt;
             &lt;devicetype&gt;Smartphone Samsung 4500&lt;/devicetype&gt;
             &lt;timestamp&gt;3456453445&lt;/timestamp&gt;
             &lt;location&gt;343-5343-64353&lt;/location&gt;
             &lt;networkid&gt;32&lt;/networkid&gt;
             &lt;messageid&gt;4003&lt;/messageid&gt;
        &lt;/header&gt;
        &lt;data&gt;
        &lt;/data&gt;
    &lt;/communicationmessage&gt;
&lt;/myproject&gt;
</code></pre>

<p>As you can see, the variable <strong>Key</strong> is an Xml-Element which is named e.g <strong>communicationmessage</strong>.</p>

<p>Now U want the template beeing converted to a JSON string, but for sure I get instead of a element <strong>communicationmessage</strong> the element <strong>"Key":"communicationmessage"</strong>. Is there a way to get something for an element like <strong>"mymessage":"This is a test"</strong> where "mymessage" is the Key and "This is a test" the value?</p>

<p>Thanks for any help </p>

<h1>Solution</h1>

<p>I solved it with this code</p>

<pre><code>public class CommunicationMessageJSONSerializer : JsonConverter {

    /// &lt;summary&gt;
    /// Used to 
    /// &lt;/summary&gt;
    /// &lt;param name="objectType"&gt;&lt;/param&gt;
    /// &lt;returns&gt;&lt;/returns&gt;
    public override bool CanConvert(Type objectType) {
        return typeof(CommunicationMessage).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo());
    }

    /// &lt;summary&gt;
    /// Deserializes the JSON string
    /// &lt;/summary&gt;
    /// &lt;param name="reader"&gt;&lt;/param&gt;
    /// &lt;param name="objectType"&gt;&lt;/param&gt;
    /// &lt;param name="existingValue"&gt;&lt;/param&gt;
    /// &lt;param name="serializer"&gt;&lt;/param&gt;
    /// &lt;returns&gt;&lt;/returns&gt;
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {

        // Load the JSON object from the reader
        JObject jsonObject = JObject.Load(reader);

        // Get the First Token
        JToken token = jsonObject.Children().First();

        // The deserialized message
        CommunicationMessage msg = ReadJSON(token);
        return msg;
    }

    /// &lt;summary&gt;
    /// This is the base method when deserializing a JSON string
    /// &lt;/summary&gt;
    /// &lt;param name="token"&gt;&lt;/param&gt;
    /// &lt;returns&gt;The root CommunicationMessage&lt;/returns&gt;
    private CommunicationMessage ReadJSON(JToken token) {

        CommunicationMessage root = new CommunicationMessage();

        if (token is JProperty) {
            if (token.First is JValue) {
                root.Key = ((JProperty)token).Name;
                root.Value = (string)((JProperty)token).Value;
            } else { 
                root.Key = ((JProperty)token).Name;

                foreach (JToken child in token.Children()) {
                    ReadRecursive(child, ref root);
                }
            }
        } else {
            foreach (JToken child in token.Children()) {
                ReadRecursive(child, ref root);
            }
        }
        return root;
    }

    /// &lt;summary&gt;
    /// This is the recursive method when deserializing a JSON string
    /// &lt;/summary&gt;
    /// &lt;param name="token"&gt;&lt;/param&gt;
    /// &lt;param name="root"&gt;The root of the coming messages&lt;/param&gt;
    private void ReadRecursive(JToken token, ref CommunicationMessage root) {

        if (token is JProperty) {

            CommunicationMessage msg = new CommunicationMessage();

            if (token.First is JValue) {
                msg.Key = ((JProperty)token).Name;
                msg.Value = (string)((JProperty)token).Value;
            } else {
                msg.Key = ((JProperty)token).Name;

                foreach (JToken child in token.Children()) {
                    ReadRecursive(child, ref msg);
                }
            }
            root.Childs.Add(msg);
        } else {
            foreach (JToken child in token.Children()) {
                ReadRecursive(child, ref root);
            }
        }
    }

    /// &lt;summary&gt;
    /// Serializes a CommuicationMessage to a JSON string
    /// &lt;/summary&gt;
    /// &lt;param name="writer"&gt;&lt;/param&gt;
    /// &lt;param name="value"&gt;&lt;/param&gt;
    /// &lt;param name="serializer"&gt;&lt;/param&gt;
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
        var msg = value as CommunicationMessage;
        WriteRecoursive(writer, msg, serializer);
    }

    /// &lt;summary&gt;
    /// This is the recursive method for serializing
    /// &lt;/summary&gt;
    /// &lt;param name="writer"&gt;&lt;/param&gt;
    /// &lt;param name="msg"&gt;&lt;/param&gt;
    /// &lt;param name="serializer"&gt;&lt;/param&gt;
    private void WriteRecoursive(JsonWriter writer, CommunicationMessage msg, JsonSerializer serializer) {

        writer.WriteStartObject();
        writer.Formatting = Formatting.Indented;

        writer.WritePropertyName(msg.Key);

        if (msg.Childs.Count &gt; 0) {
            writer.WriteStartArray();

            foreach (CommunicationMessage child in msg.Childs) {
                WriteRecoursive(writer, child, serializer);
            }

            writer.WriteEndArray();

        } else {
            writer.WriteValue(msg.Value);
        }

        writer.WriteEndObject();
    }
}
</code></pre>

<p>If you have any ideas to improve the code, let me know it. I will keep the solution updated.</p>

<p>Thanks everyone for your help</p>