4

I have the following simplest ever model class

[JsonConverter(typeof(School))]
public class School
{
  public Guid SchoolId { get; set; }
}

I have the following converter that I am using in my MVC application

public class ResponseConverter : JsonConverter
{

    public override bool CanConvert(Type objectType)
    {
        return typeof(School) == objectType;
    }

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

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var serializer2 = JsonSerializer.Create();
        serializer2.Serialize(writer, value); // This call causes WriteJson to be called recursively
    }

    public override bool CanWrite
    {
        get
        {
            return true;
        }
    }

    public override bool CanRead
    {
        get
        {
            return false;
        }
    }
}

I got an error that I have circular reference loop. When I set my application to ignore circular reference I end up getting empty string being serialized and returned in my response. When I set it to "Serialize" then I get thrown into this infinite recursive call loop.

Where is the circular reference in my model class? How do I fix this problem?

Here is my Startup.cs adding Json settings

services.AddMvc()
                .AddJsonOptions
                        (options =>
                        {
                            options.SerializerSettings.Converters.Insert(0, new RequestConverter());
                            options.SerializerSettings.Converters.Insert(0, new ResponseConverter());
                        });
dbc
  • 104,963
  • 20
  • 228
  • 340
fahadash
  • 3,133
  • 1
  • 30
  • 59
  • 1
    The problem is that you applied `[JsonConverter(typeof(School))]` to `School` directly as an attribute, so `serializer2` also picks it up and uses it, resulting in a recursive call to `ResponseConverter.WriteJson()`. But rather than allowing that to result in a stack overflow exception, Json.NET detects the recursive call as a circular reference and throws the exception you see. See [JSON.Net throws StackOverflowException when using `[JsonConvert()]`](https://stackoverflow.com/q/29719509/3744182). – dbc Jul 25 '19 at 19:33
  • There are various ways to fix this, some easier than others. Can you explain what you are trying to accomplish? – dbc Jul 25 '19 at 19:35
  • OK, I think [this answer](https://stackoverflow.com/a/57210864/3744182) to [JSON.Net throws StackOverflowException when using `[JsonConvert()]`](https://stackoverflow.com/q/29719509/3744182) is the easiest solution. Just replace `JsonSerializer.Create().Serialize(writer, value);` with `serializer.DefaultFromObject(value).WriteTo(writer);` where `DefaultFromObject` comes from the answer. Demo here: https://dotnetfiddle.net/3hamvS. Agree this is now a duplicate? – dbc Jul 25 '19 at 22:44
  • Incidentally, your code doesn't run as shown in your question. `School` isn't a `JsonConverter` so `[JsonConverter(typeof(School))] ` throws an exception when resolving a contract for `School`. Demo fiddle here: https://dotnetfiddle.net/9QoRI7. I will assume that, in your real code, it's actually `ResponseConverter`. – dbc Jul 25 '19 at 22:50

0 Answers0