Custom conversion of specific objects in JSON.NET

Viewed 28753

I'm using JSON.NET to serialize some of my objects, and i'd like to know if there is a simple way to override the default json.net converter only for a specific object?

Currently I have the following class:

public class ChannelContext : IDataContext
{
    public int Id { get; set; }
    public string Name { get; set; }
    public IEnumerable<INewsItem> Items { get; set; }
}

JSON.NET currently serializes the above like:

{
    "Id": 2,
    "Name": "name value",
    "Items": [ item_data_here ]
}

Is it possible just for that specific class to format it this way instead:

"Id_2":
{
    "Name": "name value",
    "Items": [ item data here ]
}

I'm kinda new to JSON.NET.. I was wondering if the above has something to do with writing a custom converter. I wasn't able to find any concrete examples on how to write one, If anyone can point me out to a specific source, I'll really appreciate it.

I need to find a solution which makes that specific class always convert the same, because the above context is a part of an even bigger context which the JSON.NET default converter converts just fine.

Hope my question is clear enough...

UPDATE:

I've found how to create a new custom converter (by creating a new class which inherits from JsonConverter and override it's abstract methods), I overriden the WriteJson method as follows:

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        ChannelContext contextObj = value as ChannelContext;

        writer.WriteStartObject();
        writer.WritePropertyName("id_" + contextObj.Id);
        writer.WriteStartObject();
        writer.WritePropertyName("Name");
        serializer.Serialize(writer, contextObj.Name);

        writer.WritePropertyName("Items");
        serializer.Serialize(writer, contextObj.Items);
        writer.WriteEndObject();
        writer.WriteEndObject();
    }

This indeed does the job successfully, but... I'm intrigued if there's a way to serialize the rest of the object properties by reusing the default JsonSerializer (or converter for that matter) instead of manually "Writing" the object using the jsonwriter methods.

UPDATE 2: I'm trying to get a more generic solution and came up with the following:

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteStartObject();

        // Write associative array field name
        writer.WritePropertyName(m_FieldNameResolver.ResolveFieldName(value));

        // Remove this converter from serializer converters collection
        serializer.Converters.Remove(this);

        // Serialize the object data using the rest of the converters
        serializer.Serialize(writer, value);

        writer.WriteEndObject();
    }

This works fine when adding the converter manually to the serializer, like this:

jsonSerializer.Converters.Add(new AssociativeArraysConverter<DefaultFieldNameResolver>());
jsonSerializer.Serialize(writer, channelContextObj);

But doesn't work when using the [JsonConverter()] attribute set to my custom coverter above the ChannelContext class because of a self reference loop that occurs when executing:

serializer.Serialize(writer, value)

This is obviously because my custom converter is now considered the default converter for the class once it is set with the JsonConverterAttribute, so I get an inifinite loop. The only thing I can think of, in order to solve this problem is inheriting from a basic, jsonconverter class, and calling the base.serialize() method instead... But is such a JsonConverter class even exists?

Thanks a lot!

Mikey

1 Answers
Related