Search code examples
c#asp.net-coresignalr

ASP.NET Core 2 SignalR Hub to receive complex object instead of string


I'm currently working on a ASP.NET Core 2 application using SignalR Core. I was wondering if it is possible to receive a complex object within the Hub class instead of a simple string or simple data structure.

Works - This example works fine: string message

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

Works - This example works fine as well: List<Dictionary<string, object>> message

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

Doesn't work correctly - It seems I cannot transfer complex objects via SignalR e.g. if I create a custom message class:

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
    }
}

Do you know how to transfer complex objects via a SignalR RPC?

Thank you!


Solution

  • Follow steps below for a working demo which passing Message between signalR Client and Server.

    1. Server

      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;
          }
      }
      
    2. Client

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