Search code examples
jsonjson.netsignalrasp.net-core-signalr

SignalR Core doesn't seem to respect Newtonsoft's TypeNameHandling setting


I'm passing around classes that derive from a common class. I'm finding that, despite passing deserialization valid data, the hub does not respect the TypeNameHandling and completely ignores the $type of the JSON. It deserializes to the base class regardless of what I try.

I event went and took the JSON that I was sending to the hub, pasted it into the hub code as a string, then used JsonConvert.Deserialize to see what would happen and it correctly deserialized to my derived object.

In my startup, I have

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
            {
                TypeNameHandling = TypeNameHandling.Auto
            };

I wasn't sure if this was actually being used, so I had created a test JSON converter and put a debug on the CanRead property (which I had return a static false). That got hit. This also allowed my string deserialization to work.

So what is the hub doing differently that everything seems to work except the hub?


Solution

  • despite passing deserialization valid data, the hub does not respect the TypeNameHandling and completely ignores the $type of the JSON. It deserializes to the base class regardless of what I try.

    I did a test with following code snippet, which work for me, you can refer to it.

    In Startup:

    services.AddSignalR().AddJsonProtocol(options => {
        options.PayloadSerializerSettings = new Newtonsoft.Json.JsonSerializerSettings
        {
            TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto
        };
    });
    

    Hub method:

    public async Task SendMessage1(Business mes)
    {
        //code logic here
        //...
    }
    

    Classes:

    public abstract class Business
    {
        public string Name { get; set; }
    }
    
    public class Hotel : Business
    {
        public int Stars { get; set; }
    }
    

    On client, send following JSON data to above hub method:

    var ht = { "$type": "MyNamespaceHere.Hotel, NotesRTMSignalR", "Stars": 4, "Name": "Hudson Hotel" };
    

    Test Result:

    enter image description here