0

I am using the converter from the answer of this thread (the update one): SignalR Typenamehandling

public class EnableJsonTypeNameHandlingConverter : JsonConverter
{

    [ThreadStatic]
    static bool disabled;

    // Disables the converter in a thread-safe manner.
    bool Disabled { get { return disabled; } set { disabled = value; } }

    public override bool CanWrite { get { return !Disabled; } }

    public override bool CanRead { get { return !Disabled; } }

    public override bool CanConvert(Type objectType)
    {
        if (Disabled)
            return false;
        if (objectType.Assembly.GetCustomAttributes<EnableJsonTypeNameHandlingAttribute>().Any())
            return true;
        if (objectType.GetCustomAttributes<EnableJsonTypeNameHandlingAttribute>(true).Any())
            return true;
        foreach (var type in objectType.GetInterfaces())
            if (type.GetCustomAttributes<EnableJsonTypeNameHandlingAttribute>(true).Any())
                return true;
        return false;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        using (new PushValue<bool>(true, () => Disabled, val => Disabled = val)) // Prevent infinite recursion of converters
        using (new PushValue<TypeNameHandling>(TypeNameHandling.All, () => serializer.TypeNameHandling, val => serializer.TypeNameHandling = val))
        {
            return serializer.Deserialize(reader, objectType);
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        using (new PushValue<bool>(true, () => Disabled, val => Disabled = val)) // Prevent infinite recursion of converters
        using (new PushValue<TypeNameHandling>(TypeNameHandling.All, () => serializer.TypeNameHandling, val => serializer.TypeNameHandling = val))
        {
            // Force the $type to be written unconditionally by passing typeof(object) as the type being serialized.
            serializer.Serialize(writer, value, typeof(object));
        }
    }
}

public struct PushValue<T> : IDisposable
{
    Action<T> setValue;
    T oldValue;

    public PushValue(T value, Func<T> getValue, Action<T> setValue)
    {
        if (getValue == null || setValue == null)
            throw new ArgumentNullException();
        this.setValue = setValue;
        this.oldValue = getValue();
        setValue(value);
    }

    #region IDisposable Members

    // By using a disposable struct we avoid the overhead of allocating and freeing an instance of a finalizable class.
    public void Dispose()
    {
        if (setValue != null)
            setValue(oldValue);
    }

    #endregion
}

[System.AttributeUsage(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Interface)]
public class EnableJsonTypeNameHandlingAttribute : System.Attribute
{
    public EnableJsonTypeNameHandlingAttribute()
    {
    }
}

This is how I added the converters:

    _hubConnection = new HubConnection(url);
    var converter = new EnableJsonTypeNameHandlingConverter();
    _hubConnection.JsonSerializer.Converters.Add(converter);

and

    var serializer = GlobalHost.DependencyResolver.GetService(typeof(JsonSerializer)) as JsonSerializer;
    var converter = new EnableJsonTypeNameHandlingConverter();
    serializer.Converters.Add(converter);
    GlobalHost.DependencyResolver.Register(typeof(JsonSerializer), () => serializer);

I've set breakpoints in the ReadJson and WriteJson of the converter. And I only hit the WriteJson breakpoint. ReadJson is never executed from the converter. I am sending a derived class as base class and I am not able to cast it back to the derived class.

Thypari
  • 801
  • 1
  • 6
  • 22
  • 1
    Did you add `[assembly: EnableJsonTypeNameHandlingAttribute()]` to the assembly containing your polymorphic types? Was `CanConvert` called on the receiving side? – dbc Apr 12 '18 at 17:53
  • No I did in fact not add it like that! I just added `[EnableJsonTypeNameHandlingAttribute]` but without `assembly:`. The receiving side called nothing from the converter, only the sending side. I will have a look into it on monday! – Thypari Apr 13 '18 at 22:31

0 Answers0