0
public class MyClass
{
    public string SomeProperty { get; set; }
    public List<ChildClass> Items { get; set; }
}

public class ChildClass
{
    public string IDProperty { get; set; }
    public string SomeOtherProperty { get; set; }

}

I'm writing an object that is in essence the above-defined object to a JSON string using NewtonSoft (12), but depending on the method I'm calling from I want JObject.FromObject(MyClassInstance)' to output the subitems as a JSON array, and sometimes as a JSON dictionary (using IDProperty as the dictionary key).

I tried using a JsonConverter and was able to use the WriteJson method to output both ways (by casting the list to a dictionary or an array before serializing with serializer.Serialize(writer, value)) but I wasn't able to figure out how to 'tell' the JsonConverter which way to pick as I call JObject.FromObject(MyClassInstance). My best guess is passing down a parameter within a Serializer I pass down in FromObject, but I wasn't able to find a place to pass down that info.

So, to be clear, without changing the Class attributes themselves, I'd like to be able to toggle between outputting:

{
  "SomeProperty": "myID",
  "Items": [
    {
      "cc1IDProperty": "1",
      "SomeOtherProperty": "2"
    },
    {
      "cc1IDProperty": "2",
      "SomeOtherProperty": "4"
    }
  ]
}

and

{
  "SomeProperty": "myID",
  "Items": {
    "1": {
      "cc1IDProperty": "1",
      "SomeOtherProperty": "2"
    },
    "2": {
      "cc1IDProperty": "2",
      "SomeOtherProperty": "4"
    }
  }
}
ChristopherBass
  • 301
  • 4
  • 17
  • 1
    Use the [`JObject.FromObject(Object, JsonSerializer)`](https://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Linq_JObject_FromObject_1.htm) overload and pass in a serializer constructed from `JsonSerializerSettings` with an appropriate converter included as shown in [JObject ToString with StringEnumConverter not working](https://stackoverflow.com/a/54341573/3744182). Does that answer your question sufficiently? If not, can you share a [mcve] showing the `JsonConverter` you have written which is not working? – dbc Aug 25 '21 at 18:39
  • Here is an example with my JsonConverter. This example isn't using the SerializerSettings, just a commented out attribute on the property. I wasn't able to get the serializer to add (or remove) the attribute dynamically. https://dotnetfiddle.net/Gwqiff – ChristopherBass Aug 25 '21 at 20:23
  • From Json.NET's [Serialization Guide](https://www.newtonsoft.com/json/help/html/SerializationGuide.htm#JsonConverter): *The priority of which JsonConverter is used is the JsonConverter defined by attribute on a member, then the JsonConverter defined by an attribute on a class, and finally any converters passed to the JsonSerializer.* So there is no way a converter applied by serializer settings can supersede a converter applied via a member attribute. You want the dictionary/array choice to be made in runtime. The easiest way to do that is just to add the appropriate converter to settings. – dbc Aug 25 '21 at 21:13
  • Also, can you please [edit] your question to show the exact JSON you want when serializing your list as a dictionary? – dbc Aug 25 '21 at 21:15
  • I have edited the question as you mentioned. I have also updated a fork of the fiddle I made, showing my attempt to add a Serializer - the problem is, I don't know how to attach that JsonConverter to the MyClass.Items property rather than to the MyClass object itself. https://dotnetfiddle.net/iDAi8R – ChristopherBass Aug 26 '21 at 02:00
  • I think I figured out a solution to that issue, the code I have now seems to execute on each property inside, checking if it's a List<>, and if so running on it. Not ideal since I might have other lists, but unless there's a way to check against the specific property names I don't see a better way. Fiddle updated: https://dotnetfiddle.net/iDAi8R – ChristopherBass Aug 26 '21 at 02:14
  • If you need to apply a custom converter to just one property in runtime, you can use a [custom contract resolver](https://www.newtonsoft.com/json/help/html/contractresolver.htm#CustomIContractResolverExamples). See e.g. [Custom serializer for just one property in Json.NET, without changing the model class](https://stackoverflow.com/q/53768041/3744182). – dbc Aug 30 '21 at 21:04

0 Answers0