Blazor Server(.NET7)注入ISession对象初始属性值缺失问题
你的问题核心在于Blazor Server的组件渲染时机与Scoped服务的赋值时机不匹配,结合场景具体原因如下:
预渲染机制的影响
如果你的Blazor应用启用了预渲染(默认模板通常会开启),组件会经历两个渲染阶段:- 预渲染阶段:基于HTTP请求上下文生成静态HTML返回客户端,此时的
ISession实例虽和后续SignalR连接中的实例ID一致,但登录逻辑的赋值操作是在用户的SignalR会话作用域中完成的,预渲染阶段的实例还未被赋值。 - SignalR连接阶段:客户端建立连接后,组件关联到用户的Scoped作用域,但
OnInitialized等生命周期方法不会再次执行,因此断点中看到的是预渲染阶段的空值;而按钮点击是在SignalR连接上下文内执行,能获取到已赋值的属性。
- 预渲染阶段:基于HTTP请求上下文生成静态HTML返回客户端,此时的
Scoped服务的作用域边界问题
Blazor Server中Scoped服务的作用域绑定到单个SignalR连接(用户会话),若登录逻辑在MVC/Razor Page的HTTP请求中执行,该HTTP请求的Scoped作用域和Blazor组件的SignalR连接作用域相互独立。即使你在登录请求中给Scoped的Session赋值,这个实例和Blazor组件注入的实例并非同一个——你看到的相同ID可能是调试工具显示误差,或是代码中误将Session注册为Singleton(虽你代码里用的是AddScoped)。异步赋值的时序问题
若登录后的赋值操作是异步执行的,且你在赋值完成前触发页面导航,组件生命周期方法会先于赋值操作执行,导致生命周期方法中看到空值;而按钮点击时异步赋值已完成,属性值恢复正常。属性定义语法错误
你代码中Session类的Name属性写法有误(public string Name{} = string.Empty;),正确的自动属性语法应为:public string Name { get; set; } = string.Empty;语法错误可能直接导致属性赋值失败,这也是空值问题的潜在诱因。
针对上述原因,可尝试以下解决方法:
禁用预渲染(若无需该功能)
在Program.cs的MapRazorComponents配置中,移除AddInteractiveServerRenderMode().AddPreRendering()中的AddPreRendering(),让组件仅在SignalR连接的作用域中渲染,确保生命周期方法执行时Session已完成赋值。统一登录与组件的作用域
将登录逻辑迁移到Blazor组件内执行,让赋值操作和组件注入处于同一SignalR连接的Scoped作用域中,避免跨作用域的实例不一致问题。同步等待赋值完成后再导航
若登录赋值是异步操作,需使用await等待赋值完成后,再通过NavigationManager跳转到目标页面,保证组件渲染时Session属性已填充完毕。
内容的提问来源于stack exchange,提问作者Marcin

