跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

C#中Blazor Server实战_C#服务端渲染教程【实战】

Blazor Server 的 @onclick 无响应根本原因是 SignalR 连接未建立或未被正确接管,需同时满足三处配置:Program.cs 中调用 AddServerSideBlazor() 和 MapBlazorHub()(须在 MapFallbackToPage 之前)、_Host.cshtml 中 component 标签 render-mode="Server"、组件顶层声明 @rendermode InteractiveServer;漏任一将导致点击无效、状态重复加载或 InvalidOperationException。 Blazor Server 不是“写完组件就能交互”,它依赖 SignalR 连接和三处显式配置才能让
@onclick
响应、状态不重复加载、组件不崩溃。漏掉任意一项,页面能显示,但点击没反应、数据库查两遍、甚至首次加载就报
InvalidOperationException: HttpContext is not available
。 为什么
@onclick
点了没反应? 根本原因不是代码写错,而是 SignalR 连接没建立或没被正确接管。浏览器控制台若出现
Failed to connect to signalr hub
或
Cannot send data while connecting
,基本可断定环境未就绪。
Program.cs
中必须调用
builder.Services.AddServerSideBlazor()
(不是
AddRazorComponents()
)
app.MapBlazorHub()
必须在
app.MapFallbackToPage("/_Host")
之前注册,且不能被中间件(如认证、CORS 顺序错误)拦截
_Host.cshtml
中的
标签必须设
render-mode="Server"
,且该值要与
MapFallbackToPage
的路径所指向的页面中实际使用的渲染模式一致 组件顶层需声明
@rendermode InteractiveServer
(.NET 8+ 推荐),否则即使服务端配全,组件仍以静态模式运行
OnInitializedAsync
为什么执行两次? .NET 8 Blazor Server 默认采用“预渲染 + 交互接管”流程:首次响应由服务器同步生成 HTML(第一次构造),随后浏览器建立 SignalR 连接并立即再次实例化同一组件(第二次构造)。这不是 bug,是设计行为。 C知道 CSDN推出的一款AI技术问答工具 下载 数据库查询、HTTP 调用若写在
OnInitializedAsync
里,会无感执行两次 —— 可能触发重复下单、双写日志等问题
NavigationManager.Uri
在第一次构造时为
null
或不可靠,不能用于路由判断
@inject HttpContext
在第二次构造时必然失败,因为 SignalR 连接不属于 HTTP 请求生命周期 正确做法是加守卫:
if (Circuit?.IsConnected == true)
再执行需交互能力的逻辑,或把纯初始化逻辑移到
OnParametersSet
如何避免组件被错误地当静态页渲染? 常见误操作是给所有页面统一设
render-mode="Server"
,结果 About、Help 这类纯展示页也强占 SignalR 连接,浪费资源且增加服务器压力。 纯静态内容页(无事件、无状态更新)应使用
RenderMode.Static
,它不启动 SignalR,也不创建 Circuit 混合页面可用条件渲染:
@rendermode @((IsInteractive) ? InteractiveServer.Instance : StaticInstance)
,配合参数或路由判断 全局默认设
InteractiveServer
后,个别组件需降级时,在其标签上显式写
@rendermode Static
即可覆盖 注意:
Static
模式下
@onclick
完全无效,不是“不触发”,而是根本不会绑定事件监听器 最易被忽略的是 Circuit 生命周期与请求上下文的错位 —— 很多人把
IDbContextFactory
当成万能解药,却忘了它只解决 DbContext 实例问题,而
HttpContext
、
IOptionsSnapshot
等 Scoped 服务在第二次构造时仍可能因注入时机不对而失效。

相关文章