关于 create-blazor-project
为 Blazor Web App 项目搭建提供指导的技能,面向需要创建应用的开发者。它根据交互、部署与身份验证需求选择渲染模式,并说明脚手架、配置和后续实现步骤。
主要功能
- 01收集应用需求并选择渲染模式
- 02使用 dotnet new blazor 搭建项目
- 03说明身份验证配置方式
- 04生成与渲染模式匹配的 AGENTS.md
- 05验证构建并继续实现页面
适用场景
- 01按数据展示和表单需求选择静态 SSR
- 02为实时更新或复杂组件配置交互式模式
- 03为 WebAssembly 或 Auto 项目规划客户端与 API 边界
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ dotnet/ skills --skill create-blazor-project安装后在 Claude Code 中输入/create-blazor-project确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/agents-md/auto-global.mdauto-per-page.mdserver-global.mdserver-per-page.mdssr-none.mdwebassembly-global.mdwebassembly-per-page.md详细介绍
创建 Blazor Web 应用
开始之前 — 收集需求
如果用户的请求未明确说明以下内容,请先询问,再创建项目:
- 应用的功能是什么? 列出主要页面/功能(例如,“带搜索和购物车的产品目录”)。
- 需要哪种交互? 显示数据和表单?实时更新?离线支持?丰富的拖放界面?
- 部署环境是什么? 面向互联网?内联网?使用慢速网络的移动用户?
- 是否需要身份验证? 匿名?个人帐户?组织级(Azure AD)?
选择合适的交互级别
Blazor 渲染模式是一个渐进式的级别体系。从满足需求的最简单级别开始,只有在有明确理由时才升级。
Static SSR ──→ SSR + Enhanced Nav ──→ Interactive Server ──→ Interactive WebAssembly
simplest most complex
决策规则
| 如果应用需要…… | 使用 | 原因 |
|---|---|---|
| 显示数据、简单表单、页面间链接 | 静态 SSR (-int None) | 无 JS 运行时、无 circuit、无需下载 WebAssembly。表单通过 HTML POST 工作。增强导航让体验更流畅。 |
| 上述所有功能 + 少量具有客户端行为的组件(实时搜索、实时更新、复杂表单向导) | 交互式 Server,按页面启用 (-int Server) | 只有需要交互的组件才通过 @rendermode 启用交互。其余部分保持静态。服务器端执行,可完整访问 .NET,无需 API 层。 |
| 大多数页面都需要丰富的交互(仪表板、拖放、聊天) | 交互式 Server,全局启用 (-int Server -ai) | 默认情况下,每个组件都可交互。用户体验一致,思维模型更简单。取舍:每位用户都会在服务器上占用一个 SignalR circuit。 |
| 网络延迟是个问题、用户使用移动网络/较差的网络连接,或应用必须支持离线工作 | 交互式 WebAssembly (-int WebAssembly) | 代码在浏览器中运行。无需往返服务器即可消除延迟,但需要 .Client 项目、用于访问数据的 API 层,并且首次访问时会将 .NET 运行时下载到浏览器。若要支持离线,请在创建项目后启用 PWA:添加 service worker 和 manifest(模板默认不包含这些内容)。 |
| 首次加载快(Server)+ 后续延迟低(WebAssembly) | 交互式 Auto (-int Auto) | 首次访问使用 Server;后续访问使用缓存的 WebAssembly 运行时。配置最复杂 — 请参阅下方的 Auto 限制。只有在 Server 和 WebAssembly 的限制都适用时才选择此模式。 |
默认建议: 从 -int Server(按页面启用)开始。它适用于绝大多数应用。只有在具体需求要求时,才升级为全局启用或 WebAssembly。
Auto 模式限制
Auto 模式意味着组件代码最初在服务器上运行,之后的访问则在浏览器中运行。这会带来一些实际限制:
- 所有交互式组件都必须位于
.Client项目中 — 与 WebAssembly 相同。 - 交互式组件不能直接访问服务器 — 不能使用 EF
DbContext、文件系统或仅限服务器的服务。所有数据访问都必须通过 HTTP API。 - 两个
Program.cs文件都必须注册匹配的服务 — 服务器端和客户端 DI 容器都必须为交互式组件注入的所有服务提供实现。 - 代码不能假定自身的执行环境 — 不能访问
HttpContext,也不能在没有RendererInfo检查的情况下使用仅限浏览器的 API。 - 在两种模式下都进行测试 — 开发期间在 Server 上正常工作的组件,在生产环境中可能会在 WebAssembly 上出错(第二次访问时)。请测试这两种路径。
注意事项
- 不要因为 WebAssembly“很酷”就选择它 — 它会增加一个
.Client项目,强制通过 API 访问数据,并在首次访问时向浏览器下载约 10MB 的内容。 - 除非你能清楚说明为什么单独使用 Server 和单独使用 WebAssembly 都不够,否则不要选择 Auto。
- 对于大多数页面都是只读内容的应用,不要选择全局交互 — 按页面启用交互可以让静态页面保持快速,并减少服务器内存占用。
创建项目
仅静态 SSR(显示数据和简单表单)
dotnet new blazor -o {AppName} -int None
没有交互式运行时。默认通过 blazor.web.js 启用增强导航。
交互式 Server,按页面启用(推荐默认设置)
dotnet new blazor -o {AppName} -int Server
页面默认是静态的。对需要交互性的组件添加 @rendermode InteractiveServer。
交互式 Server,全局启用
dotnet new blazor -o {AppName} -int Server -ai
在 App.razor 中通过 <Routes @rendermode="InteractiveServer" /> 使所有页面都具有交互性。
交互式 WebAssembly,按页面启用
dotnet new blazor -o {AppName} -int WebAssembly
创建 {AppName}(服务器端)和 {AppName}.Client(WebAssembly)项目。交互式组件必须位于 .Client 中。
交互式 WebAssembly,全局启用
dotnet new blazor -o {AppName} -int WebAssembly -ai
交互式 Auto,按页面启用
dotnet new blazor -o {AppName} -int Auto
交互式 Auto,全局启用
dotnet new blazor -o {AppName} -int Auto -ai
使用身份验证
在上述任意命令后追加 -au Individual:
dotnet new blazor -o {AppName} -int Server -au Individual
-au Individual 会使用 SQLite(CLI)或 SQL Server(Visual Studio)搭建 ASP.NET Core Identity。Identity 页面始终使用静态 SSR,不使用交互式呈现模式。
blazor 模板仅支持 -au Individual。对于组织身份验证(Microsoft Entra ID、Azure AD B2C),请先使用 -au Individual 搭建项目,然后将 Identity 提供程序替换为 Microsoft.Identity.Web / OIDC 中间件,并在 appsettings.json 中配置租户。
模板创建的内容
单个项目(静态 SSR、Server)
{AppName}/
├── Components/
│ ├── App.razor # Root component — sets <HeadOutlet> and <Routes>
│ ├── Routes.razor # Wraps <Router> with route discovery
│ ├── Layout/
│ │ ├── MainLayout.razor # App shell with nav, header, footer
│ │ └── MainLayout.razor.css
│ └── Pages/
│ └── Home.razor # @page "/" — first page
├── Program.cs # Service registration and middleware
├── wwwroot/ # Static files (CSS, images)
└── {AppName}.csproj
两个项目(WebAssembly、Auto)
{AppName}/ # Server project — hosts the app
├── Components/ # Server-only components (static SSR pages, layouts)
│ ├── App.razor
│ ├── Routes.razor
│ └── Layout/
├── Program.cs # Server Program.cs
└── {AppName}.Client/ # Client project — WebAssembly components
├── Pages/ # Interactive components go HERE
├── Program.cs # Client Program.cs
└── _Imports.razor
规则: 使用 InteractiveWebAssembly 或 InteractiveAuto 的组件必须位于 .Client 项目中。它们可以引用共享代码,但不能引用仅限服务器端的类型(EF DbContext、服务器端服务)。
Program.cs 配置
模板会为所选模式生成正确的 Program.cs。请确认这些注册与你的预期一致:
仅静态 SSR
// Program.cs
builder.Services.AddRazorComponents();
// ...
app.MapRazorComponents<App>();
Server(按页面或全局启用)
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
// ...
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
WebAssembly(按页面或全局启用)
// Server Program.cs
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents();
// ...
app.MapRazorComponents<App>()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof({AppName}.Client._Imports).Assembly);
// Client Program.cs
builder.Services.AddAuthorizationCore();
// Register HttpClient, other client-side services
创建项目 AGENTS.md
搭建项目后,在项目根目录(与 .csproj 同级)创建一个 AGENTS.md 文件。对于包含两个项目的设置,请将其放在服务器项目根目录中。
根据所选模式,从 assets/agents-md/ 中选择匹配的模板:
| 模式 | 模板文件 |
|---|---|
静态 SSR(-int None) | assets/agents-md/ssr-none.md |
Server,按页面启用(-int Server) | assets/agents-md/server-per-page.md |
Server,全局启用(-int Server -ai) | assets/agents-md/server-global.md |
WebAssembly,按页面启用(-int WebAssembly) | assets/agents-md/webassembly-per-page.md |
WebAssembly,全局启用(-int WebAssembly -ai) | assets/agents-md/webassembly-global.md |
Auto,按页面启用(-int Auto) | assets/agents-md/auto-per-page.md |
Auto,全局启用(-int Auto -ai) | assets/agents-md/auto-global.md |
将模板内容复制到项目的 AGENTS.md,并将每个 {AppName} 替换为实际项目名称。如果搭建时启用了身份验证(-au Individual),请添加 ## Authentication 部分,说明已配置 ASP.NET Core Identity,且 Components/Account/ 下的 Identity 页面始终使用静态 SSR,不要为其添加 @rendermode。
搭建项目并创建 AGENTS.md 后,继续实现用户请求的功能。 删除默认模板页面(Counter、Weather),并将其替换为实际的应用页面。
Auto(按页面或全局启用)
// Server Program.cs
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents();
// ...
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof({AppName}.Client._Imports).Assembly);
App.razor — 全局启用与按页面启用
全局启用与按页面启用的区别完全体现在 App.razor 中:
按页面启用(默认)
<!DOCTYPE html>
<html>
<head>
<HeadOutlet />
</head>
<body>
<Routes />
<script src="_framework/blazor.web.js"></script>
</body>
</html>
不要在 <Routes> 或 <HeadOutlet> 上设置 @rendermode。各个页面可选择启用。
全局启用
<!DOCTYPE html>
<html>
<head>
<HeadOutlet @rendermode="InteractiveServer" />
</head>
<body>
<Routes @rendermode="InteractiveServer" />
<script src="_framework/blazor.web.js"></script>
</body>
</html>
根据需要,将 InteractiveServer 替换为 InteractiveWebAssembly 或 InteractiveAuto。
脚手架搭建后
- 验证是否可构建:
dotnet build - 运行:
dotnet run(如果是双项目设置,请在服务项目中运行) - 添加你的第一个页面: 在服务项目的
Components/Pages/中创建一个.razor文件;如果是 WebAssembly 组件,则在.Client项目的Pages/中创建。
注意事项
- 不要使用
dotnet new blazorwasm—— 这会创建一个没有服务端渲染功能的独立 WebAssembly SPA。请改用blazor模板,并添加-int WebAssembly。 - 不要在使用
-int None创建的项目中手动添加AddInteractiveServerComponents(),并期待它能正常运行——你还需要@rendermode指令,且可能需要修改App.razor。如果需要从根本上更改模式,请重新搭建脚手架。 - 不要将面向 WebAssembly 的组件放在服务项目中——它们在预渲染期间可以正常运行,但交接后会失败。