SignalR 2.0 change Json Serializer to support derived type objects
Asked Answered
A

1

17

Please note that I'm explicitly referencing SignalR 2.0 here ... I've seen some (nasty) approaches for this with SignalR 1.1/1.2 ... but none for 2.0 yet.

Has anyone had any success with changing the SignalR 2.0 default json serializer to enable the sending of derived types? Based on what I’ve read about SignalR 2.0 this should be possible, however, I’m not having any luck and have not found a full example anywhere.

Here is how I started … any help would be appreciated.

My Startup.cs

    [assembly: OwinStartup(typeof(SignalRChat.Startup))]
    namespace SignalRChat
    {

        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                // this should allow the json serializer to maintain the object structures
                var serializer = new JsonSerializer()
                {
                    PreserveReferencesHandling = PreserveReferencesHandling.Objects,
                    TypeNameHandling = TypeNameHandling.Objects,
                    TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
                };

                // register it so that signalr can pick it up
                GlobalHost.DependencyResolver.Register(typeof(JsonSerializer), () => serializer);

                app.MapSignalR();
            }
        }
    }

Method on the Hub

    public void AddStock(Stock stock)
    {
        string stockType = stock.GetType().ToString();
        Console.WriteLine("The type of stock we got was: " + stockType);
    }

My console test app (this publishes to the hub)

    myDataHub.Invoke("AddStock", new NyseStock()
    {
        Company = "Microsoft",
        NyseSymbol = "MSFT"
    });

    myDataHub.Invoke("AddStock", new DaxStock()
    {
        Company = "Microsoft",
        DaxSymbol = "DMSFT"
    });

Just for good measure Stock.cs

    namespace Messages
    {
        public class Stock
        {
            public string Company
            {
                get;
                set;
            }
            public decimal Price
            {
                get;
                set;
            }
        }

        public class NyseStock : Stock
        {
            public string NyseSymbol
            {
                get;
                set;
            }
        }

        public class DaxStock : Stock
        {
            public string DaxSymbol
            {
                get;
                set;
            }
        }
    }

My first inclination was that I neglected to setup the serializer in the client. So I added the following after the creation of the connection but before the creation of the hub proxy :

    myConnection = new HubConnection("http://localhost:64041/");
    // Update the serializer to use our custom one
    myConnection.JsonSerializer = new JsonSerializer()
    {
         PreserveReferencesHandling = PreserveReferencesHandling.Objects,
         TypeNameHandling = TypeNameHandling.Objects,
         TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
    };

    //Make proxy to hub based on hub name on server
    myDataHub = myConnection.CreateHubProxy("DataHub");

This however just resulted in an InvalidOperationException (Data cannot be sent because the connection is in the disconnected state. Call start before sending any data.) during the myDataHub.Invoke(..) invocations.

Atlantic answered 20/10, 2013 at 2:41 Comment(2)
Did you ever figure this out? I'm coming across the same issue.Berget
Same problem here...Bootless
I
5

It's been a while since this question was asked. For future reference, myConnection.Start() method needs to be called after creating the proxy, like this

myConnection = new HubConnection(endpoint);

proxy = _conn.CreateHubProxy("DataHub");
proxy.On<string>("ServerEvent", ClientHandler);

myConnection.Start();

proxy.Invoke("hubMethod", ...);
Inexperienced answered 19/2, 2014 at 23:16 Comment(1)
I does not the answer the real question which is "How to setup this on the Server?". It only solves the small issue mentioned at the end of the question, when author is mentioning what he already tried.Beattie

© 2022 - 2024 — McMap. All rights reserved.