You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的序列化与反序列化环节:

  1. 字段未被序列化:SignalR默认使用的JSON序列化器(如System.Text.Json)默认只序列化公共属性,而你的ConnectedDigiModel中使用的是公共字段(public string ConnectionID = "";)。这导致服务端发送集合时,对象的字段无法被序列化为JSON,客户端接收到的内容不完整,无法匹配到对应的ConnectedDigiModel类型,因此ConnectedDigisToSTM方法不会触发。

  2. 缺少无参构造函数: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 02:32:52