create-blazor-project
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCreate a Blazor Web App
创建Blazor Web应用
Before You Start — Gather Requirements
开始之前 — 收集需求
If the user's request doesn't make the following clear, ask before scaffolding:
- What does the app do? List the main screens/features (e.g., "product catalog with search and shopping cart").
- What kind of interactivity is needed? Displaying data and forms? Real-time updates? Offline support? Rich drag-and-drop UI?
- Deployment environment? Internet-facing? Intranet? Mobile users on slow connections?
- Authentication needed? Anonymous? Individual accounts? Organizational (Azure AD)?
如果用户的请求未明确以下信息,请在搭建前询问:
- 应用的功能是什么? 列出主要界面/功能(例如:"带搜索和购物车的产品目录")。
- 需要什么样的交互性? 展示数据和表单?实时更新?离线支持?丰富的拖放UI?
- 部署环境? 面向互联网?内网?使用慢速网络的移动用户?
- 需要身份验证吗? 匿名?个人账户?组织账户(Azure AD)?
Pick the Right Interactivity Level
选择合适的交互级别
Blazor render modes are a progression scale. Start at the simplest level that satisfies the requirements and only move up when there's a concrete reason.
Static SSR ──→ SSR + Enhanced Nav ──→ Interactive Server ──→ Interactive WebAssembly
simplest most complexBlazor渲染模式是一个递进的层级。从满足需求的最简单级别开始,只有在有具体理由时才升级。
Static SSR ──→ SSR + Enhanced Nav ──→ Interactive Server ──→ Interactive WebAssembly
simplest most complexDecision Rules
决策规则
| If the app needs... | Use | Why |
|---|---|---|
| Display data, simple forms, links between pages | Static SSR ( | No JS runtime, no circuit, no WebAssembly download. Forms work via HTML POST. Enhanced navigation makes it feel snappy. |
| Everything above + a few components with client-side behavior (live search, real-time updates, complex form wizards) | Interactive Server, per-page ( | Only the components that need interactivity opt in with |
| Most pages need rich interactivity (dashboards, drag-and-drop, chat) | Interactive Server, global ( | Every component is interactive by default. Consistent UX, simpler mental model. Trade-off: every user holds a SignalR circuit on the server. |
| Network latency is a problem, users are on mobile/poor connections, or the app must work offline | Interactive WebAssembly ( | Code runs in the browser. Eliminates round-trip latency but requires a |
| Fast initial load (Server) + low latency after (WebAssembly) | Interactive Auto ( | First visit uses Server; subsequent visits use cached WebAssembly runtime. Most complex setup — see Auto constraints below. Only choose when both Server and WebAssembly constraints apply. |
Default recommendation: Start with (per-page). It covers the vast majority of apps. Upgrade to global or WebAssembly only when a specific requirement demands it.
-int Server| 如果应用需要... | 使用 | 原因 |
|---|---|---|
| 展示数据、简单表单、页面间链接 | Static SSR ( | 无需JS运行时、无需电路、无需下载WebAssembly。表单通过HTML POST工作。增强导航让应用感觉更流畅。 |
| 以上所有功能 + 少数需要客户端行为的组件(实时搜索、实时更新、复杂表单向导) | Interactive Server,每页模式 ( | 仅需要交互性的组件通过 |
| 大多数页面需要丰富的交互性(仪表板、拖放、聊天) | Interactive Server,全局模式 ( | 默认所有组件都是交互式的。用户体验一致,思维模型更简单。权衡:每个用户都会在服务器上占用一个SignalR电路。 |
| 网络延迟是问题、用户使用移动设备/网络不佳,或应用必须支持离线 | Interactive WebAssembly ( | 代码在浏览器中运行。消除往返延迟,但需要 |
| 快速初始加载(Server模式) + 后续低延迟(WebAssembly模式) | Interactive Auto ( | 首次访问使用Server模式;后续访问使用缓存的WebAssembly运行时。设置最复杂——请参阅下文的Auto模式限制。仅当Server和WebAssembly模式的限制都适用时才选择此模式。 |
默认推荐: 从(每页模式)开始。它适用于绝大多数应用。仅当特定需求要求时,才升级到全局模式或WebAssembly模式。
-int ServerAuto Mode Constraints
Auto模式限制
Auto mode means your component code runs on the server first, then in the browser on subsequent visits. This creates real constraints:
- All interactive components must live in the project — same as WebAssembly.
.Client - No direct server access from interactive components — no EF , no file system, no server-only services. All data access must go through HTTP APIs.
DbContext - Both files must register matching services — the server and client DI containers must both provide implementations for any service an interactive component injects.
Program.cs - Code must not assume its execution environment — no access, no browser-only APIs without
HttpContextguards.RendererInfo - Test in both modes — a component that works on Server during development may break on WebAssembly in production (second visit). Test both paths.
Auto模式意味着组件代码首先在服务器上运行,然后在后续访问时在浏览器中运行。这带来了实际限制:
- 所有交互式组件必须位于项目中 —— 与WebAssembly模式相同。
.Client - 交互式组件无法直接访问服务器 —— 不能使用EF 、文件系统、仅服务器端服务。所有数据访问必须通过HTTP API。
DbContext - 两个文件必须注册匹配的服务 —— 服务器和客户端DI容器必须为交互式组件注入的任何服务提供实现。
Program.cs - 代码不能假设其执行环境 —— 不能访问,没有
HttpContext保护的情况下不能使用仅浏览器API。RendererInfo - 在两种模式下测试 —— 开发期间在Server模式下工作的组件可能在生产环境的WebAssembly模式下(第二次访问)崩溃。测试两种路径。
Don'ts
注意事项
- Don't pick WebAssembly "because it's cool" — it adds a project, forces API-mediated data access, and downloads ~10MB to the browser on first visit.
.Client - Don't pick Auto unless you can articulate why Server alone and WebAssembly alone are both insufficient.
- Don't pick global interactivity for apps where most pages are read-only content — per-page keeps the static pages fast and reduces server memory.
- 不要因为"很酷"就选择WebAssembly模式——它会增加一个项目,强制通过API进行数据访问,并且首次访问时需要向浏览器下载约10MB的内容。
.Client - 除非你能明确说明为什么单独使用Server模式和单独使用WebAssembly模式都不满足需求,否则不要选择Auto模式。
- 对于大多数页面为只读内容的应用,不要选择全局交互性——每页模式保持静态页面快速,并减少服务器内存占用。
Scaffold the Project
搭建项目
Static SSR Only (display data + simple forms)
仅Static SSR(展示数据 + 简单表单)
shell
dotnet new blazor -o {AppName} -int NoneNo interactive runtime. Enhanced navigation enabled by default via .
blazor.web.jsshell
dotnet new blazor -o {AppName} -int None无交互式运行时。默认通过启用增强导航。
blazor.web.jsInteractive Server, Per-Page (recommended default)
Interactive Server,每页模式(推荐默认)
shell
dotnet new blazor -o {AppName} -int ServerPages are static by default. Add to components that need interactivity.
@rendermode InteractiveServershell
dotnet new blazor -o {AppName} -int Server页面默认是静态的。为需要交互性的组件添加。
@rendermode InteractiveServerInteractive Server, Global
Interactive Server,全局模式
shell
dotnet new blazor -o {AppName} -int Server -aiAll pages interactive via in .
<Routes @rendermode="InteractiveServer" />App.razorshell
dotnet new blazor -o {AppName} -int Server -ai所有页面通过中的变为交互式。
App.razor<Routes @rendermode="InteractiveServer" />Interactive WebAssembly, Per-Page
Interactive WebAssembly,每页模式
shell
dotnet new blazor -o {AppName} -int WebAssemblyCreates (server) and (WebAssembly) projects. Interactive components must live in .
{AppName}{AppName}.Client.Clientshell
dotnet new blazor -o {AppName} -int WebAssembly创建(服务器)和(WebAssembly)项目。交互式组件必须位于中。
{AppName}{AppName}.Client.ClientInteractive WebAssembly, Global
Interactive WebAssembly,全局模式
shell
dotnet new blazor -o {AppName} -int WebAssembly -aishell
dotnet new blazor -o {AppName} -int WebAssembly -aiInteractive Auto, Per-Page
Interactive Auto,每页模式
shell
dotnet new blazor -o {AppName} -int Autoshell
dotnet new blazor -o {AppName} -int AutoInteractive Auto, Global
Interactive Auto,全局模式
shell
dotnet new blazor -o {AppName} -int Auto -aishell
dotnet new blazor -o {AppName} -int Auto -aiWith Authentication
带身份验证
Append to any command above:
-au Individualshell
dotnet new blazor -o {AppName} -int Server -au Individual-au IndividualThe template only supports . For organizational auth (Microsoft Entra ID, Azure AD B2C), scaffold with first, then replace the Identity provider with / OIDC middleware and configure the tenant in .
blazor-au Individual-au IndividualMicrosoft.Identity.Webappsettings.json在上述任何命令后追加:
-au Individualshell
dotnet new blazor -o {AppName} -int Server -au Individual-au Individualblazor-au Individual-au IndividualMicrosoft.Identity.Webappsettings.jsonWhat the Template Creates
模板创建的内容
Single project (Static SSR, Server)
单项目(Static 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{AppName}/
├── Components/
│ ├── App.razor # 根组件 — 设置<HeadOutlet>和<Routes>
│ ├── Routes.razor # 用路由发现包装<Router>
│ ├── Layout/
│ │ ├── MainLayout.razor # 带有导航、页眉、页脚的应用外壳
│ │ └── MainLayout.razor.css
│ └── Pages/
│ └── Home.razor # @page "/" — 首页
├── Program.cs # 服务注册和中间件
├── wwwroot/ # 静态文件(CSS、图片)
└── {AppName}.csprojTwo projects (WebAssembly, Auto)
双项目(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.razorRule: Components using or must live in the project. They can reference shared code but cannot reference server-only types (EF , server-side services).
InteractiveWebAssemblyInteractiveAuto.ClientDbContext{AppName}/ # 服务器项目 — 托管应用
├── Components/ # 仅服务器端组件(静态SSR页面、布局)
│ ├── App.razor
│ ├── Routes.razor
│ └── Layout/
├── Program.cs # 服务器端Program.cs
└── {AppName}.Client/ # 客户端项目 — WebAssembly组件
├── Pages/ # 交互式组件放在此处
├── Program.cs # 客户端Program.cs
└── _Imports.razor规则: 使用或的组件必须位于项目中。它们可以引用共享代码,但不能引用仅服务器端类型(EF 、服务器端服务)。
InteractiveWebAssemblyInteractiveAuto.ClientDbContextProgram.cs Wiring
Program.cs配置
The template generates the correct for the chosen mode. Verify these registrations match your intent:
Program.cs模板会为所选模式生成正确的。验证这些注册是否符合你的意图:
Program.csStatic SSR Only
仅Static SSR
csharp
// Program.cs
builder.Services.AddRazorComponents();
// ...
app.MapRazorComponents<App>();csharp
// Program.cs
builder.Services.AddRazorComponents();
// ...
app.MapRazorComponents<App>();Server (per-page or global)
Server模式(每页或全局)
csharp
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
// ...
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();csharp
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
// ...
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();WebAssembly (per-page or global)
WebAssembly模式(每页或全局)
csharp
// Server Program.cs
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents();
// ...
app.MapRazorComponents<App>()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof({AppName}.Client._Imports).Assembly);csharp
// Client Program.cs
builder.Services.AddAuthorizationCore();
// Register HttpClient, other client-side servicescsharp
// 服务器端Program.cs
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents();
// ...
app.MapRazorComponents<App>()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof({AppName}.Client._Imports).Assembly);csharp
// 客户端Program.cs
builder.Services.AddAuthorizationCore();
// 注册HttpClient、其他客户端服务Create Project AGENTS.md
创建项目AGENTS.md文件
After scaffolding, create an file in the project root (next to the ). For two-project setups, put it in the server project root.
AGENTS.md.csprojPick the matching template from based on the chosen mode:
assets/agents-md/| Mode | Template file |
|---|---|
Static SSR ( | |
Server, per-page ( | |
Server, global ( | |
WebAssembly, per-page ( | |
WebAssembly, global ( | |
Auto, per-page ( | |
Auto, global ( | |
Copy the template contents into the project's and replace every with the actual project name. If auth was scaffolded (), add an section noting that ASP.NET Core Identity is configured and that Identity pages under are always static SSR — do not add to them.
AGENTS.md{AppName}-au Individual## AuthenticationComponents/Account/@rendermodeAfter scaffolding the project and creating AGENTS.md, continue implementing the features the user requested. Remove default template pages (Counter, Weather) and replace them with the actual application pages.
搭建完成后,在项目根目录(旁边)创建文件。对于双项目结构,放在服务器项目根目录。
.csprojAGENTS.md根据所选模式从中选择匹配的模板:
assets/agents-md/| 模式 | 模板文件 |
|---|---|
Static SSR ( | |
Server,每页模式 ( | |
Server,全局模式 ( | |
WebAssembly,每页模式 ( | |
WebAssembly,全局模式 ( | |
Auto,每页模式 ( | |
Auto,全局模式 ( | |
将模板内容复制到项目的中,并将所有替换为实际项目名称。如果搭建了身份验证(),添加一个部分,说明已配置ASP.NET Core Identity,并且下的Identity页面始终是静态SSR——不要为它们添加。
AGENTS.md{AppName}-au Individual## 身份验证Components/Account/@rendermode搭建项目并创建AGENTS.md后,继续实现用户请求的功能。 删除默认模板页面(Counter、Weather),替换为实际的应用页面。
Auto (per-page or global)
Auto模式(每页或全局)
csharp
// Server Program.cs
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents();
// ...
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof({AppName}.Client._Imports).Assembly);csharp
// 服务器端Program.cs
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents();
// ...
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof({AppName}.Client._Imports).Assembly);App.razor — Global vs Per-Page
App.razor — 全局模式 vs 每页模式
The difference between global and per-page interactivity is entirely in :
App.razor全局模式和每页模式的区别完全在中:
App.razorPer-page (default)
每页模式(默认)
razor
<!DOCTYPE html>
<html>
<head>
<HeadOutlet />
</head>
<body>
<Routes />
<script src="_framework/blazor.web.js"></script>
</body>
</html>No on or . Individual pages opt in.
@rendermode<Routes><HeadOutlet>razor
<!DOCTYPE html>
<html>
<head>
<HeadOutlet />
</head>
<body>
<Routes />
<script src="_framework/blazor.web.js"></script>
</body>
</html><Routes><HeadOutlet>@rendermodeGlobal
全局模式
razor
<!DOCTYPE html>
<html>
<head>
<HeadOutlet @rendermode="InteractiveServer" />
</head>
<body>
<Routes @rendermode="InteractiveServer" />
<script src="_framework/blazor.web.js"></script>
</body>
</html>Replace with or as appropriate.
InteractiveServerInteractiveWebAssemblyInteractiveAutorazor
<!DOCTYPE html>
<html>
<head>
<HeadOutlet @rendermode="InteractiveServer" />
</head>
<body>
<Routes @rendermode="InteractiveServer" />
<script src="_framework/blazor.web.js"></script>
</body>
</html>根据需要将替换为或。
InteractiveServerInteractiveWebAssemblyInteractiveAutoAfter Scaffolding
搭建后的操作
- Verify it builds:
dotnet build - Run it: (in the server project if two-project setup)
dotnet run - Add your first page: Create a file in
.razor(server project) orComponents/Pages/(Pages/project for WebAssembly components).Client
- 验证构建:
dotnet build - 运行应用: (如果是双项目结构,在服务器项目中运行)
dotnet run - 添加你的第一个页面: 在(服务器项目)或
Components/Pages/(WebAssembly组件的Pages/项目)中创建.Client文件.razor
Don'ts
注意事项
- Don't use — that creates a standalone WebAssembly SPA without server-side rendering. Use the
dotnet new blazorwasmtemplate withblazorinstead.-int WebAssembly - Don't manually add to a project created with
AddInteractiveServerComponents()and expect it to work — you also need the-int Nonedirectives and potentially@rendermodechanges. Re-scaffold if the mode needs to change fundamentally.App.razor - Don't put WebAssembly-targeted components in the server project — they'll work during prerender but fail after handoff.
- 不要使用—— 它会创建一个没有服务器端渲染的独立WebAssembly单页应用。请改用带
dotnet new blazorwasm选项的-int WebAssembly模板。blazor - 不要手动向使用创建的项目添加
-int None并期望它能正常工作——你还需要AddInteractiveServerComponents()指令,可能还需要修改@rendermode。如果需要从根本上更改模式,请重新搭建。App.razor - 不要将面向WebAssembly的组件放在服务器项目中——它们在预渲染期间可以工作,但在交接后会失败。