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
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 Réponses :
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.
Suivez les étapes ci-dessous pour une démonstration fonctionnelle qui transmet le Message
entre le client et le serveur signalR.
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(); }
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; } }
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
Pouvez-vous également ajouter le code côté client pour le hub où
SendMessage
accepte le paramètreMessage
? 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.