
在 Blazor Web App 中构建纯 Static SSR 应用-int None无交互模式的完整实践指南【免费下载链接】skillsRepository for skills to assist AI coding agents with .NET and C#项目地址: https://gitcode.com/GitHub_Trending/skills17/skills本篇技术指南基于 GitHub 精选仓库 skills17/skills 中的 dotnet-blazor 插件聚焦create-blazor-project技能为「无交互None / Static SSR」模式生成的 AGENTS.md 模板ssr-none.md系统讲解如何用dotnet new blazor -int None搭建一个不含任何交互运行时、纯服务端渲染的 Blazor Web App。读完本文你将掌握该模式的适用场景、脚手架命令、项目结构与Program.cs接线、增强导航原理、SSR 表单与查询字符串绑定方式、数据访问策略以及必须避开的常见陷阱从而为「展示数据 简单表单」类应用选择并落地最简渲染架构。一、模式定位什么是 Static SSRNone在 Blazor 的渲染模式递进谱系中Static SSR 处于最简一端。create-blazor-project技能的 SKILL.md 用一条递进链路概括了所有模式Static SSR ──→ SSR Enhanced Nav ──→ Interactive Server ──→ Interactive WebAssembly simplest most complexssr-none.md模板开头的配置表明确给出了该模式的两个核心属性SettingValueInteractivity ModeNone (Static SSR)Interactivity ScopeN/A也就是说项目不注册任何交互运行时没有 SignalR circuit没有 WebAssembly 下载所有渲染都发生在服务器上。页面在请求时由服务端生成完整 HTML 返回给浏览器用户看到的纯静态 HTML 文档。Interactivity Scope为 N/A 意味着「按页启用交互」这一概念在该模式下不存在——没有任何页面或组件可以声明rendermode。适用场景与决策依据SKILL.md 的决策规则表给出了 Static SSR 的明确适用条件应用只需要显示数据、提交简单表单、在页面之间跳转链接。典型例子包括内容型网站、产品目录、文档站、公告页等。其优势在于无 JS 运行时、无 circuit、无 WebAssembly 下载资源占用最低表单通过标准 HTML POST 工作无需任何交互机制增强导航Enhanced Navigation让页面切换有接近 SPA 的即时感。该模式的选型原则在技能评估测试 eval.yaml 中得到了可验证的体现第一个评估场景「大学课程目录 选课注册表单」明确要求「标准 HTML 表单无向导、无实时校验」评估规则要求输出匹配-int(eractivity)? None并验证产物满足「Program.cs只调用AddRazorComponents()而无任何AddInteractive*链、App.razor不在Routes或HeadOutlet上设置rendermode」——这正是 Static SSR 的判别式。因此当需求中没有实时交互、实时校验或富客户端行为时-int None就是最简且正确的选择。二、脚手架用一条命令创建项目创建 Static SSR 项目的命令非常简单来自 SKILL.md 的「Static SSR Only」小节dotnet new blazor -o {AppName} -int None其中{AppName}替换为实际项目名。-int是--interactivity的简写None表示不启用任何交互。该命令生成的是单项目结构不会像 WebAssembly/Auto 那样额外创建.Client项目从源码结构看模板产出的目录布局如下{AppName}/ ├── Components/ │ ├── App.razor # 根组件 — 设置 HeadOutlet 和 Routes │ ├── Routes.razor # 用 Router 包裹并做路由发现 │ ├── Layout/ │ │ ├── MainLayout.razor # 应用外壳导航、头部、页脚 │ │ └── MainLayout.razor.css │ └── Pages/ │ └── Home.razor # page / — 首页 ├── Program.cs # 服务注册与中间件 ├── wwwroot/ # 静态文件CSS、图片 └── {AppName}.csproj如果需要认证可在命令后追加-au Individualdotnet new blazor -o {AppName} -int None -au Individual注意-au Individual会搭建 ASP.NET Core IdentityCLI 下使用 SQLite且 Identity 页面始终是静态 SSR——它们不使用任何交互渲染模式这一点与整个项目「无交互运行时」的基调天然一致。模板生成的 Program.cs模板会根据所选模式生成对应的Program.csStatic SSR 的接线是四种模式中最精简的SKILL.md 给出的参考实现为// Program.cs builder.Services.AddRazorComponents(); // ... app.MapRazorComponentsApp();这里没有任何AddInteractiveServerComponents()、AddInteractiveWebAssemblyComponents()之类的注册链。AddRazorComponents()只注册了静态 SSR 所需的组件渲染与端点映射服务MapRazorComponentsApp()将根组件App映射为请求入口。从源码结构可以推断这正是-int None与交互模式的本质区别所在交互模式需要额外的AddInteractive*服务链与对应的AddInteractive*RenderMode()端点扩展而 None 模式一概不需要。三、渲染配置静态渲染 默认开启的增强导航ssr-none.md的「Rendering configuration」小节对运行时行为做了三点声明纯静态服务端渲染项目创建自dotnet new blazor -int None无任何交互运行时不存在 SignalR circuit也不存在 WebAssembly 运行时增强导航默认启用通过blazor.web.js实现让页面切换「感觉即时」instant却无需任何交互运行时参与。增强导航的工作原理App.razor中会引用_framework/blazor.web.js脚本见 SKILL.md 中 per-page 的App.razor示例script src_framework/blazor.web.js/scriptblazor.web.js在页面加载后拦截导航事件仅抓取目标页面中发生变化的 DOM 片段并原地替换而不是整页刷新。因为不需要为每个页面重新下载全套 JS 运行时这种「局部更新」让多页面应用拥有了接近 SPA 的切换速度同时页面本身依然是服务器渲染的静态 HTML——这就是 Static SSR 在无交互前提下依然「快」的原因。注意增强导航只是体验优化它不改变页面的渲染模型导航前后页面内容仍然完全由服务器生成。增强表单提交增强能力同样作用于表单在 SSR 的EditForm上添加Enhance属性即可实现无整页刷新的 SPA 式表单提交。collect-user-input技能collect-user-input/SKILL.md给出了用法EditForm ModelModel OnValidSubmitSave FormNamequick Enhance增强导航/增强表单遵循渐进增强原则浏览器支持时拦截并局部更新不支持时自动回退为完整页面刷新因此可以放心使用。四、添加新组件与页面ssr-none.md的「Adding new components」小节定义了该模式下新增代码的组织规则可路由页面在Components/Pages/下新建.razor文件并用page /route声明路由共享组件直接放在Components/目录下禁止添加rendermode项目没有配置任何交互运行时任何组件都不应声明渲染模式表单用 HTML POST通过[SupplyParameterFromForm]做模型绑定查询字符串参数使用[SupplyParameterFromQuery]绑定。这里的关键纪律是页面默认就是静态渲染不需要也不能额外声明任何模式。团队在后续开发中若有人误加rendermode将会因运行时未注册而失败——这正是模板在「Donts」中反复强调的原因。五、SSR 表单用[SupplyParameterFromForm]处理用户输入由于没有交互运行时bind、oninput等事件绑定一概不可用表单必须走「HTML POST 服务端模型绑定」的经典 Web 流程。ssr-none.md明确指出Forms use standard HTML POST with[SupplyParameterFromForm]for model binding。collect-user-input技能collect-user-input/SKILL.md对该模式下的表单写法给出了完整的实现参考。静态 SSR 页面的典型表单结构为EditForm ModelEmployee OnValidSubmitHandleSubmit FormNameemployee DataAnnotationsValidator / ValidationSummary / InputText idname bind-ValueEmployee.Name / button typesubmitSave/button /EditForm code { [SupplyParameterFromForm] private EmployeeModel? Employee { get; set; } protected override void OnInitialized() Employee ?? new(); private async Task HandleSubmit() { // 保存 Employee } }关键细节一??初始化不能省略collect-user-input/SKILL.md特别强调了这个 SSR 模式下的核心机制[SupplyParameterFromForm] private ContactModel? Contact { get; set; } protected override void OnInitialized() Contact ?? new();GET 请求时Contact为null??负责创建空模型供表单渲染POST 请求时框架会用提交的表单数据填充Contact??不会覆盖已填充的值。省略??会导致 GET 时Contact为 null表单无法渲染或访问属性时抛空引用异常。关键细节二多表单共页需唯一FormName同一页面上存在多个表单时必须为每个表单指定唯一的FormName并用[SupplyParameterFromForm(FormName ...)]将模型与具体表单配对EditForm ModelSearch OnSubmitDoSearch FormNamesearch.../EditForm EditForm ModelContact OnValidSubmitSaveContact FormNamecontact.../EditForm[SupplyParameterFromForm(FormName search)] private SearchModel? Search { get; set; } [SupplyParameterFromForm(FormName contact)] private ContactModel? Contact { get; set; }在 SSR 模式下FormName标识表单、[SupplyParameterFromForm]绑定 POST 数据在交互模式下这套机制会被忽略改用bind-Value——但在 None 模式下没有交互分支表单行为完全由上述 SSR 机制决定。关键细节三防伪令牌是硬性要求ssr-none.md的环境约束明确列出表单使用 HTML POST 时必须包含AntiforgeryToken /。使用EditForm时防伪令牌通常会自动生成但若在静态页面中使用原生form元素则必须手动加入form methodpost AntiforgeryToken / !-- 表单字段 -- /formcollect-user-input/SKILL.md在「Donts」中给出了对应的警告忘记在原生form中放置AntiforgeryToken /服务器会直接拒绝该 POST 请求。这是 ASP.NET Core 内置的防跨站请求伪造CSRF保护在纯 SSR 项目中承担着所有写操作的安全屏障职责。查询字符串绑定对于搜索、筛选、分页等场景ssr-none.md规定使用[SupplyParameterFromQuery]绑定 URL 查询参数[SupplyParameterFromQuery] public string? SearchTerm { get; set; } [SupplyParameterFromQuery(Name page)] public int Page { get; set; }框架会在每次请求时自动从查询字符串解析并填充这些属性配合EditForm的 GET 提交即可实现「搜索 分享链接」等经典服务端模式。collect-user-input/SKILL.md还展示了结合OnInitialized进行服务端过滤的用法例如在初始化时按SearchTerm对数据源执行Where(i i.Name.Contains(searchTerm, StringComparison.OrdinalIgnoreCase))过滤——整个流程不需要任何客户端脚本。六、数据访问直接注入服务无需 API 层ssr-none.md的「Data access」小节是 Static SSR 在架构上最省心的部分Components can inject services directly — EF Core DbContext, file system, server-only APIs. No HTTP API layer needed.因为所有代码都在服务器进程内执行组件可以直接注入 EF CoreDbContext、文件系统访问、邮件发送、服务器专用 API 客户端等任何注册到 DI 容器的服务。这与 WebAssembly/Auto 模式形成鲜明对比——后者要求交互组件只能通过 HTTP API 访问数据并且服务器与客户端两个Program.cs必须注册镜像服务。而 None 模式只有一个项目、一个 DI 容器数据访问链路最短组件 (.razor) → 注入的服务器服务 (DbContext / IFileProvider / HttpClient) → 数据这一特性让内容型应用的开发成本降到最低写一个page /courses页面注入AppDbContext用foreach渲染课程列表即可无需任何 DTO、Controller 或 API 客户端代码。七、环境约束与边界ssr-none.md的「Environment constraints」小节完整列举了该模式的能力边界无 SignalR circuit、无 WebAssembly所有渲染都发生在服务器端不存在客户端运行时会话表单走 HTML POST必须配合[SupplyParameterFromForm]与AntiforgeryToken /HttpContext可通过[CascadingParameter]获得静态渲染发生在请求上下文内因此可以安全访问HttpContext如读取请求头、Cookie、用户身份这是交互组件SignalR 生命周期内做不到的浏览器 APIJS interop不可用因为没有交互运行时来执行 JavaScript 调用IJSRuntime在此模式下没有对应的执行通道。换句话说该模式适合「服务端能完成一切」的应用页面数据、表单提交、认证、Cookie、服务端重定向都原生可用凡是依赖浏览器端 JavaScript 的能力DOM 操作、localStorage、navigator等都不存在。从架构上可以推断如果某个需求强烈依赖浏览器 API 或实时交互就应该升级到 Interactive Server 或 WebAssembly 模式而不是试图在 None 模式下打补丁。八、Donts必须避开的五个陷阱ssr-none.md以独立的「Donts」清单收尾这是给后续 Agent/开发者最重要的守则不要添加rendermode InteractiveServer或任何交互渲染模式——项目没有注册交互运行时加了也会失败不要只给Program.cs加AddInteractiveServerComponents()——如果没有同步更新App.razor例如在Routes上设置渲染模式服务注册与组件渲染声明不匹配同样无法工作若需根本性切换模式应当重新脚手架SKILL.md 的 Donts 也强调不要手工拼接AddInteractiveServerComponents()后指望它生效模式需要变更时请重新生成项目不要使用onclick等事件处理器——它们依赖交互渲染模式静态 SSR 下不会工作用户操作应通过表单提交和页面链接来表达不要使用IJSRuntime——没有交互运行时来执行 JavaScript 调用对应地collect-user-input/SKILL.md也强调不要在 Static SSR 表单中使用bind或oninput——这些同样要求交互性。这些禁令背后是同一个根因None 模式刻意去掉了交互运行时一切依赖该运行时的 API 都不可用。与其对抗约束不如遵循「表单 链接 服务端处理」的经典 Web 模型。九、验证与后续脚手架完成后按 SKILL.md 的「After Scaffolding」建议进行验证dotnet build # 验证可编译 dotnet run # 运行查看效果随后进入实际功能开发在Components/Pages/添加首屏页面替换模板自带的 Counter、Weather 示例页。整个技能的评估体系eval.yaml正是围绕「正确选择渲染模式」展开对于「浏览 简单表单」型应用验证标准就是-int None、AddRazorComponents()无AddInteractive*链、App.razor无rendermode——这三条与本文描述完全一致也可以作为任何 None 模式项目自查的三项黄金标准。总结Static SSR-int None是 Blazor 渲染模式光谱上最简、最稳的一端单项目、零运行时、直接注入服务、表单走 HTML POST配合默认开启的增强导航即可获得接近 SPA 的体感。它最适合「展示数据 简单表单 页面跳转」的内容型应用。选用它的前提是接受其边界——没有事件处理、没有 JS interop、没有客户端状态。当需求超出这些边界时才需要考虑升级到 Server 或 WebAssembly 模式而在边界之内它是最低复杂度、最高可靠性的选择。【免费下载链接】skillsRepository for skills to assist AI coding agents with .NET and C#项目地址: https://gitcode.com/GitHub_Trending/skills17/skills创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考