ASP.NET Core 2 SignalR Hub для получения сложного объекта вместо строки - PullRequest
0 голосов
/ 14 января 2019

В настоящее время я работаю над приложением ASP.NET Core 2, использующим SignalR Core. Мне было интересно, возможно ли получить сложный объект в классе Hub вместо простой строки или простой структуры данных.

Работает - Этот пример отлично работает: string message

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

Работает - этот пример также хорошо работает: List<Dictionary<string, object>> message

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

Не работает правильно. Кажется, я не могу передать сложные объекты через SignalR, например. если я создаю собственный класс сообщения:

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

Знаете ли вы, как передавать сложные объекты с помощью RPC SignalR?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 15 января 2019

Выполните шаги ниже для рабочей демонстрации, которая передает Message между клиентом и сервером signalR.

  1. Сервер

    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. Клиент

    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();
    }
    
0 голосов
/ 14 января 2019

Вы можете использовать Newtonsoft.Json Nuget.

Там у вас есть JsonConverter, который может сериализовать ваш объект.

Итак, в вашем примере:

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

И на вашем клиенте вы можете преобразовать его обратно в объект. У него есть нативный API, поэтому вы просто звоните

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

Теперь сообщение снова является объектом, который вы отправляете с сервера.

И, конечно, вы можете использовать JsonConvert.DeserializeObject<T>() для преобразования строки json, которую вы получаете от клиента, в Объект.

...