ASP.NET Controller调用SignalR Hub时Clients为null报错如何修复
问题根因
你不能手动实例化继承自Hub的SignalR集线器类,这类实例的生命周期完全由SignalR运行时管理,只有当客户端发起连接请求时,SignalR才会自动创建Hub实例并为Clients、Context等内置属性注入有效值。你自己new SignalRClientHub()创建的实例没有经过初始化流程,Clients属性自然为null,触发空引用报错。
修复步骤
- 首先确认程序启动配置中已经正确注册SignalR服务并配置Hub路由,以ASP.NET Core 6+的
Program.cs为例:
var builder = WebApplication.CreateBuilder(args); // 注册SignalR核心服务 builder.Services.AddSignalR(); // 其他服务注册逻辑... var app = builder.Build(); // 其他中间件配置... // 映射SignalRClientHub的访问路由,和前端chat.js里配置的路径保持一致 app.MapHub<SignalRClientHub>("/SignalRClient"); app.Run();
- 调整Controller代码,通过依赖注入获取
IHubContext<SignalRClientHub>来发送消息,删除手动实例化Hub的逻辑:
public class YourController : Controller { private readonly IHubContext<SignalRClientHub> _hubContext; // 通过构造函数注入IHubContext实例,由DI容器自动完成赋值 public YourController(IHubContext<SignalRClientHub> hubContext) { _hubContext = hubContext; } public async Task<IActionResult> Index(long sessionId) { // 原有数据库变更逻辑 // 直接用注入的IHubContext发送消息,不需要调用Hub内的SendMessage方法 await _hubContext.Clients.All.SendAsync("ReceiveMessage", null, null); // 原有剩余逻辑 return View(); } }
- 额外注意修正前端的SignalR库引入路径,你当前的路径拼写少了一个
s,会导致前端加载SignalR失败:
原错误路径:
<script src="~/js/ignalr/dist/browser/signalr.js"></script>
修正后:
<script src="~/js/signalr/dist/browser/signalr.js"></script>
补充说明
如果没有客户端主动调用集线器方法的需求,SignalRClientHub类里自定义的SendMessage方法可以直接删除,服务端主动推送消息完全通过IHubContext实现即可。
内容的提问来源于stack exchange,提问作者Biraj Dahal
相关产品推荐
相关产品推荐

