net hubconnectionbuilder framework for asp c# signalr jsonserializer derived-types

c# - hubconnectionbuilder - SignalR 2.0 cambia Json Serializer para admitir objetos de tipo derivado



signalr vs signalr core (1)

Ha pasado un tiempo desde que se hizo esta pregunta. Para futuras referencias, el método myConnection.Start() debe llamarse después de crear el proxy, como este

myConnection = new HubConnection(endpoint); proxy = _conn.CreateHubProxy("DataHub"); proxy.On<string>("ServerEvent", ClientHandler); myConnection.Start(); proxy.Invoke("hubMethod", ...);

Tenga en cuenta que estoy haciendo referencia explícita a SignalR 2.0 aquí ... He visto algunos enfoques (desagradables) para esto con SignalR 1.1 / 1.2 ... pero ninguno para 2.0 todavía.

¿Alguien ha tenido éxito al cambiar el serializador json predeterminado de SignalR 2.0 para permitir el envío de tipos derivados? De acuerdo con lo que he leído sobre SignalR 2.0, esto debería ser posible, sin embargo, no estoy teniendo suerte y no he encontrado un ejemplo completo en ninguna parte.

Así es como comencé ... cualquier ayuda sería apreciada.

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

Método en el Hub

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

Mi aplicación de prueba de consola (esto publica en el hub)

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

Sólo por si acaso 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; } } }

Mi primera inclinación fue que olvidé configurar el serializador en el cliente. Así que agregué lo siguiente después de la creación de la conexión pero antes de la creación del proxy concentrador:

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

Sin embargo, esto solo resultó en una InvalidOperationException (los datos no se pueden enviar porque la conexión está en estado desconectado. La llamada comienza antes de enviar cualquier dato) durante las invocaciones de myDataHub.Invoke (..).