SignalR客户端方法未触发:集合类型参数引发的问题
SignalR集合类型参数无法触发客户端方法问题
服务端代码
public class ConnectionHandlerModel { public static Collection<ConnectedDigiModel> Digis = new Collection<ConnectedDigiModel>(); } public class ConnectedDigiModel { public string ConnectionID = ""; public string DeviceNr = ""; public string GroupName = ""; public string UserName = ""; public ConnectedDigiModel(string ConnectionID, string username) { this.ConnectionID = ConnectionID; this.UserName = username; } } public override async Task OnConnectedAsync() { var username = Context.GetHttpContext().Request.Query["username"]; ConnectionHandlerModel.Digis.Add(new ConnectedDigiModel(Context.ConnectionId, username)); } public async Task SendConnectedDigis() { await Clients.Caller.SendAsync("ConnectedDigisToSTM", ConnectionHandlerModel.Digis); }
客户端代码
private async void btnGetConnectedDigis_Click(object sender, EventArgs e) { await digiConnection.InvokeAsync("SendConnectedDigis"); } digiConnection.On<Collection<ConnectedDigiModel>>("ConnectedDigisToSTM", (digis) => { foreach (ConnectedDigiModel digi in digis) { listBox1.Invoke(new MethodInvoker(delegate () { listBox1.Items.Add(digi.UserName.ToString()); })); } });
问题
客户端的ConnectedDigisToSTM方法未被触发。当改为仅发送字符串时方法可以正常执行,为何集合类型参数会导致方法无法执行?
解答
核心问题出在ConnectedDigiModel的序列化与反序列化环节:
字段未被序列化:SignalR默认使用的JSON序列化器(如System.Text.Json)默认只序列化公共属性,而你的
ConnectedDigiModel中使用的是公共字段(public string ConnectionID = "";)。这导致服务端发送集合时,对象的字段无法被序列化为JSON,客户端接收到的内容不完整,无法匹配到对应的ConnectedDigiModel类型,因此ConnectedDigisToSTM方法不会触发。缺少无参构造函数:JSON反序列化器需要无参构造函数来实例化对象,而你的
ConnectedDigiModel只有带参数的构造函数。反序列化失败后,客户端无法解析传入的集合对象,同样会导致方法不触发。
修复方案
修改ConnectedDigiModel,将字段改为属性并添加无参构造函数:
public class ConnectedDigiModel { // 将字段改为带get/set的公共属性 public string ConnectionID { get; set; } = ""; public string DeviceNr { get; set; } = ""; public string GroupName { get; set; } = ""; public string UserName { get; set; } = ""; // 添加无参构造函数 public ConnectedDigiModel() {} public ConnectedDigiModel(string connectionID, string userName) { ConnectionID = connectionID; UserName = userName; } }
同时确保客户端的ConnectedDigiModel结构与服务端完全一致(同样是属性、有无参构造函数),这样SignalR就能正确完成序列化和反序列化,客户端的方法也会正常触发。
内容的提问来源于stack exchange,提问作者Spufi
相关产品推荐
相关产品推荐

