0

I have the following class:

public string Prop1 {get;set;}
public string Prop2 {get;set;}

[JsonConverter(typeof(CustomFieldConverter))]    
public Dictionary<string,string> MyDict {get;set;}

public bool ShouldSerializeMyDict()
{
   return MyDict != null && MyDict.Count > 0;
}

I would like to serialize the class so that it appears like this:

{
   "prop1":"value1",
   "prop2":"value2",
   "dictKey1":"dictValue1",
   "dictKey2":"dictValue2",
   ........
}

Here is my JsonConverter class

public class CustomFieldConverter : JsonConverter
{
   public override bool CanConvert(Type objectType)
   {
      return objectType == typeof(Dictionary<string, string>);
   }

public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
   Dictionary<string, string> dic = new Dictionary<string, string>();
   JObject jo = JObject.Load(reader);
   foreach (JProperty jp in jo.Properties())
   {
      //Check some conditions here before adding
      dic.Add(jp.Name, value);

   }

   return dic;
}

public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
               
   JObject jo = new();

   Dictionary<string, string> dic = (Dictionary<string, string>)value;

   if (dic.Count == 0)
   {
      return;
   }


   foreach (var kvp in dic)
   {
      jo.Add(kvp.Key, kvp.Value);
   }

   jo.WriteTo(writer);
}

However, what I end up getting is this:

{
   "Prop1":"value1",
   "Prop2":"value2",
   "MyDict":{
      "dictKey1":"dictValue1",
      "dictKey2":"dictValue2",
      ........
   }
}

Whatever I try, I don't seem to be able to get the desired results. Could anybody please point me in the right direction so that I can get this output?

There is a suggestion that I use a Dictionary<string, object> or Dictionary<string, JToken> as per this suggestion. However this is not a great solution as I specifically want it to be a Dictionary<string, string>. The other suggestion means that I have to manage the serialization and deserialization of the whole class which I was trying to avoid but I may have to go down that route if there is no other way.

zeiddev
  • 662
  • 7
  • 23
  • 1
    If you are willing to change your `Dictionary` to `Dictionary` you can apply `[JsonExtensionData]` and you will get what you want, as shown in [How to serialize a Dictionary as part of its parent object using Json.Net](https://stackoverflow.com/a/23786127). – dbc Aug 02 '22 at 17:22
  • 1
    If you require a `Dictionary` you will need to use something like `[JsonTypedExtensionData]` from [this answer](https://stackoverflow.com/a/40094403) to [How to deserialize a child object with dynamic (numeric) key names?](https://stackoverflow.com/q/40088941). – dbc Aug 02 '22 at 17:55
  • Do either of those answer your question? – dbc Aug 02 '22 at 17:55
  • BTW, in your question you write *I would like to serialize the class so that it appears like this:* twice, and the results shown are contradictory. Is the second one, following *However, what I end up getting is this*, a typo? – dbc Aug 02 '22 at 17:56
  • Does this answer your question? [How to serialize a Dictionary as part of its parent object using Json.Net](https://stackoverflow.com/questions/14893614/how-to-serialize-a-dictionary-as-part-of-its-parent-object-using-json-net) – Marius Aug 02 '22 at 18:37
  • @dbc Thanks for pointing out my copy and paste error. I have removed the extraneous text. – zeiddev Aug 02 '22 at 19:48
  • Does this answer your question? [Json Deserialization - How do I add remaining items into a dictionary?](https://stackoverflow.com/questions/55046717/json-deserialization-how-do-i-add-remaining-items-into-a-dictionary) – Charlieface Aug 02 '22 at 23:50
  • Thank you @dbc for your great suggestions. I added some comments to my post to explain why I was reluctant to use them but I may have to if there is no alternative. – zeiddev Aug 03 '22 at 08:13
  • @zeiddev applying `[JsonTypedExtensionData]` plus `[JsonConverter(typeof(TypedExtensionDataConverter))]` from [How to deserialize a child object with dynamic (numeric) key names?](https://stackoverflow.com/a/40094403) doesn't require you to *manage the serialization and deserialization of the whole class* since the converter works by using Json.NET's own contract data. – dbc Aug 03 '22 at 14:09

1 Answers1

0

you can add [JsonExtensionData] to your dictionary

public class MyClass
{
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }

    [JsonExtensionData]
    public Dictionary<string, JToken> MyDict { get; set; }

}

you don't need ShouldSerializeMyDict() in this case

result

{
  "Prop1": "prop1",
  "Prop2": "prop2",
  "dictKey1": "dictValue1",
  "dictKey2": "dictValue2"
}
Serge
  • 40,935
  • 4
  • 18
  • 45