Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json.NET custom JsonConverter being ignored

I have a generic class, whose children I want to serialize with the value of only one of its attributes.

To this end, I wrote a custom JsonConverter and attached it to the base class with the JsonConverter(Type) Attribute - however, it does not ever seem to be called. For reference, as shown in the example below, I am serializing a List<> of the object using the System.Web.Mvc.Controller.Json() method.

If there is an altogether better way of achieving the same result, I'm absolutely open to suggestions.

Example

View function

public JsonResult SomeView()
{
    List<Foo> foos = GetAListOfFoos();
    return Json(foos);
}

Custom JsonConverter

class FooConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        System.Diagnostics.Debug.WriteLine("This never seems to be run");
        // This probably won't work - I have been unable to test it due to mentioned issues.
        serializer.Serialize(writer, (value as FooBase<dynamic, dynamic>).attribute);
    }

    public override void ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override bool CanConvert(Type objectType)
    {
        System.Diagnostics.Debug.WriteLine("This never seems to be run either");
        return objectType.IsGenericType
            && objectType.GetGenericTypeDefinition() == typeof(FooBase<,>);
    }
}

Foo base class

[JsonConverter(typeof(FooConverter))]
public abstract class FooBase<TBar, TBaz>
    where TBar : class
    where TBaz : class
{
    public TBar attribute;
}

Foo implementation

public class Foo : FooBase<Bar, Baz>
{
    // ...
}

Current output

[
    {"attribute": { ... } },
    {"attribute": { ... } },
    {"attribute": { ... } },
    ...
]

Desired output

[
    { ... },
    { ... },
    { ... },
    ...
]
like image 824
ackwell Avatar asked Aug 15 '14 10:08

ackwell


2 Answers

First of all System.Web.Mvc.Controller.Json() doesn't work with Json.NET - it uses JavaScriptSerializer that doesn't know anything about your Json.NET stuff. If you still want to use System.Web.Mvc.Controller.Json() call you should do something like this. Also change WriteJson to this:

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    serializer.Serialize(writer, ((dynamic)value).attribute);
}

I think this should make your code work.

like image 133
yar_shukan Avatar answered Oct 13 '22 22:10

yar_shukan


What happened to me was, I added the using statement automatically as suggested by Visual Studio. And by mistake added using System.Text.Json.Serialization; instead of using Newtonsoft.Json;

So I was using System.Text.Json.Serialization.JsonConverterAttribute on the target class. Which is (correctly) ignored by Json.Net.

like image 36
Tedy Pranolo Avatar answered Oct 13 '22 21:10

Tedy Pranolo