ASP.NET Core 2 SignalR Hub 接收复杂对象而不是字符串

问题描述 投票:0回答:4

我目前正在使用 SignalR Core 开发 ASP.NET Core 2 应用程序。我想知道是否可以在 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
    }
}

您知道如何通过 SignalR RPC 传输复杂对象吗?

谢谢!

c# asp.net-core signalr
4个回答
7
投票

您可以使用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 字符串转换为对象。


1
投票

按照以下步骤进行工作演示,在 signalR 客户端和服务器之间传递

Message

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

1
投票

如果您考虑使用 JSON 解析只是为了将多个对象/参数传递到客户端,那么还有一种替代方法。

服务器端(C#)。您可以将任意数量的参数传递给匿名对象数组。

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

客户端(Typescript)

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

我有一个稍微详细一点的答案这里


0
投票

在我的例子中,我在 hub 方法上接收到一个自定义类,但该类的属性没有设置器,因此所有属性都是默认值。

因此每个属性都需要在反序列化期间分配

{ get; set; }

© www.soinside.com 2019 - 2024. All rights reserved.