SignalR 2.0 изменяет Json Serializer для поддержки объектов производного типа

Обратите внимание, что я прямо ссылаюсь на SignalR 2.0 здесь... Я видел некоторые (неприятные) подходы для этого с SignalR 1.1/1.2... но еще не для 2.0.

Кто-нибудь имел успех в изменении стандартного json-сериализатора SignalR 2.0 для включения отправки производных типов? Основываясь на том, что Ive читал о SignalR 2.0, это должно быть возможно, однако, мне не повезло и нигде не нашел полного примера.

Вот как я начал... любая помощь будет оценена.

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();
            }
        }
    }

Метод на концентраторе

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

Моя консольная тестовая программа (это публикуется в хабе)

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

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

Только для хорошей меры 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;
            }
        }
    }

Мое первое наклонение состояло в том, что я пренебрег настройкой сериализатора в клиенте. Поэтому я добавил следующее после создания соединения, но до создания прокси-сервера:

    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");

Однако это привело к исключению InvalidOperationException (данные не могут быть отправлены, поскольку соединение находится в отключенном состоянии. Начало вызова перед отправкой любых данных.) во время вызовов myDataHub.Invoke(..).

Ответы

Ответ 1

Прошло некоторое время с тех пор, как был задан этот вопрос. Для дальнейшего использования метод myConnection.Start() должен быть вызван после создания прокси-сервера, например

myConnection = new HubConnection(endpoint);

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

myConnection.Start();

proxy.Invoke("hubMethod", ...);