Can you extend the default JsonConverter used in JSON.NET for collections?
Asked Answered
S

3

27

I'm trying to write a custom JsonConverter for cases where a person subclasses a list or collection, but then adds extra properties to the subclass (see here). The current implementation of JSON.NET just changes the list into an array of child objects and ignores all of the added properties. So I want to write a new JsonConverter that treats the object as if it wasn't a List and to just serialize everything else as normal, but then to add a new property in the serialization called '_Items' where the actual array of data is stored.

Now I've already written a class that does exactly this for our specific List subclass, but I had to manually specify all the properties one-by-one. But if I could write a converter that treats this just as a normal object, then manually handle the items, I'd be golden. I don't even care if I end up duplicating half of another class (or even more!) but I'd love to make a reusable converter for these cases. However, as I said, I can't find the default converter to start from.

So... anyone know where that is?

Stravinsky answered 4/5, 2011 at 9:3 Comment(2)
See How do I get json.net to serialize members of a class deriving from List<T>?Floyfloyd
Not quite what I was looking for, but it does give me an idea of how to go.Stravinsky
V
16

There is no 'default converter' in JSON.NET.

If you are able to examine the JsonSerializerInternalWriter class, look at the SerializeValue method. In it, there is the 'converter find and perform' phase at the top. However, if there is no converter that matches, it resorts to the contract type serialization (the switch statement).

I haven't found a way (a correct way or a graceful hack) to be able to perform a generic contract serialization (ex: parsing an object as normal) with an extended custom serialization on an entity (which I assume you are trying to do).

Verge answered 11/9, 2013 at 19:59 Comment(1)
Kind of crazy that this has never been fixed so the default logic is correctly factored into a DefaultJsonConverter.Gluteal
I
4

As @dbc said here, you can override CanRead and CanWrite to return false and register CustomAsDefaultConvertor : JsonConverter for your property.

My case:

public class AsDefaultConverter : JsonConverter<JObject>
{
    public override JObject ReadJson(JsonReader reader, Type objectType, JObject existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, JObject value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override bool CanWrite => false;

    public override bool CanRead => false;
}

MyModel:

public class MyModel
{
    /// <summary>
    /// Gets or sets event id
    /// </summary>
    public string EventId { get; set; }

    /// <summary>
    /// Gets or sets trigger name
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// Gets or sets arguments
    /// </summary>
    [JsonConverter(typeof(AsDefaultConverter))]
    public JObject Arguments { get; set; }

    /// <summary>
    /// Gets or sets trigger creation date
    /// </summary>
    public DateTimeOffset Created { get; set; }

    /// <summary>
    /// Gets or sets trigger creator
    /// </summary>
    public User CreatedBy { get; set; }
} 

In startUp registration I have overrided default JsonSerialization on my custom, but for property JObject Arguments I have specified converter that I need in this case.

Inappetence answered 17/8, 2019 at 4:12 Comment(0)
G
1

Not sure since when and if this is the answer but there is property JsonConvert.DefaultSettings which seem used to get JsonSerializerSettings internally

https://www.newtonsoft.com/json/help/html/DefaultSettings.htm

Gospel answered 27/12, 2021 at 7:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.