3
votes

ASP.NET Core 2 SignalR Hub pour recevoir un objet complexe au lieu d'une chaîne

Je travaille actuellement sur une application ASP.NET Core 2 utilisant SignalR Core. Je me demandais s'il était possible de recevoir un objet complexe dans la classe Hub au lieu d'une simple chaîne ou d'une simple structure de données.

Fonctionne - Cet exemple fonctionne bien: message de chaîne

XXX

Fonctionne - Cet exemple fonctionne également très bien: List > message

public class Message 
{
   public int MessageId { get; set; }

   public List<Dictionary<string, object>> Items { get; set; }

   public List<string> TextMessages { get; set; }
}

public class MyHub : Hub
{
    public Task SendMessage(Message message)
    {
        // ... some logic
    }
}

Ne fonctionne pas correctement - Il semble que je ne puisse pas transférer d'objets complexes via SignalR, par exemple si je crée une classe de message personnalisée:

public class MyHub : Hub
{
    public Task SendMessage(List<Dictionary<string, object>> message)
    {
        // ... some logic
    }
}

Savez-vous comment transférer des objets complexes via un RPC SignalR?

Merci!


3 commentaires

Pouvez-vous également ajouter le code côté client pour le hub où SendMessage accepte le paramètre Message ? Tant que vous envoyez le bon JSON, cela devrait passer.


Merci, je travaille uniquement en .NET, pas de JavaScript cependant ... peut-être que je manque juste l'attribut [Serializable] ...


Partagez-nous votre code client signalR.


3 Réponses :


2
votes

Vous pouvez utiliser le Newtonsoft.Json Nuget.

Là vous avez un JsonConverter qui peut sérialiser votre objet.

Donc dans votre exemple:

connection.on("ReceiveMessage",  (message) => { 
    let messageObject = JSON.parse(message);
    // Other code here
});

Et sur votre client, vous pouvez le reconvertir en objet. Il a une API native, il vous suffit d'appeler

    public class MyHub : Hub
    {
          public Task SendMessage(Message message)
          {
             var messageJsonString = JsonConvert.SerializeObject<Message>(message);
             // some logic
           }
    }

Le message est à nouveau l'objet que vous envoyez depuis le serveur.

Et bien sûr, vous pouvez utilisez JsonConvert.DeserializeObject () pour convertir une chaîne json que vous recevez du client en un objet.


0 commentaires

1
votes

Suivez les étapes ci-dessous pour une démonstration fonctionnelle qui transmet le Message entre le client et le serveur signalR.

  1. Serveur

    private static async void Connect()
    {
        var hubConnectionBuilder = new HubConnectionBuilder();
        #region Worked
        var hubConnection = hubConnectionBuilder.WithUrl("https://localhost:44381/timeHub", options =>
        {
    
        }).Build();
        #endregion
    
        await hubConnection.StartAsync();
        await hubConnection.SendAsync("UpdateTime", $"From Client");
        var item1 = new Dictionary<string, object> {
            { "T1", new { Name = "TT1" } },
            { "T2", new { Name = "TT2" } },
            { "T3", new { Name = "TT3" } },
        };
        var item2 = new Dictionary<string, object> {
            { "T11", new { Name = "TT11" } },
            { "T12", new { Name = "TT12" } },
            { "T13", new { Name = "TT13" } },
        };
    
        await hubConnection.SendAsync("SendMessage", new Message {
            MessageId = 1,
            Items = new List<Dictionary<string, object>> {
                item1,
                item2
            },
            TextMessages = new List<string> {
                "H1",
                "H2"
            }
        });
        var on = hubConnection.On("ReceiveMessage", OnReceivedAction);
        Console.WriteLine($"Client is Start");
        Console.ReadLine();
        on.Dispose();
        await hubConnection.StopAsync();
    }
    
  2. Client

    public class TimeHub: Hub
    {
        public async Task UpdateTime(string message)
        {
            if (Clients != null)
            {
                await Clients?.All.SendAsync("ReceiveMessage", message);
            }
        }
        public Task SendMessage(Message message)
        {
            // ... some logic
            return Task.CompletedTask;
        }
    }
    


0 commentaires

0
votes

Si vous envisagez d'utiliser l'analyse JSON uniquement pour passer plusieurs objets / paramètres côté client, il existe une alternative.

Côté serveur (C #). Vous pouvez transmettre n'importe quel nombre de paramètres au tableau d'objets anonymes.

private alertHandler = (someObject: any, someNumber: number, someString: string) => {
    console.log(someObject, someNumber, someString);
};

Côté client (Typescript)

SendCoreAsync("MethodName", new object[] {someObject, someNumber, someString });

J'ai une réponse un peu plus détaillée ici


0 commentaires