深入解读 Scalar.AspNetCore:ASP.NET Core 集成从 1.2 到 2.17 的能力演进与实战指南
【免费下载链接】scalarScalar is an open-source API platform: 🌐 Modern REST API Client 📖 Beautiful API References ✨ 1st-Class OpenAPI/Swagger Support项目地址: https://gitcode.com/GitHub_Trending/sc/scalar
Scalar.AspNetCore 是 Scalar 为 ASP.NET Core 生态提供的 NuGet 集成包,它把 OpenAPI/Swagger 文档渲染为可直接交互的 API Reference 页面。本文以该集成包的 CHANGELOG.md 为主线,梳理其从早期版本到 2.17.x 的功能演进脉络,并结合仓库中的源码与配套文档,带你完整掌握多 OpenAPI 文档、AsyncAPI 支持、认证预配置、子路径部署、静态资源缓存与 CSP nonce 等核心能力,读完即可在自己的 .NET 项目中落地一套开箱即用的 API 文档方案。
一、Scalar.AspNetCore 是什么
根据 integrations/dotnet/aspnetcore/README.md 的定义,Scalar.AspNetCore是一个提供“渲染基于 OpenAPI/Swagger 文档的精美 API Reference”能力的 NuGet 包。它解决了 .NET 开发者常见的痛点:Swagger UI 样式老旧、交互能力弱,而自研文档站点又成本高昂。
从源码结构看,该集成目录下同时维护了三个面向不同 OpenAPI 生态的包:
Scalar.AspNetCore:核心包,直接对接 .NET 9+ 内置的Microsoft.AspNetCore.OpenApi文档生成器;Scalar.AspNetCore.Microsoft:为 Microsoft 版 OpenAPI 文档生成器提供特性到 OpenAPI 转换器的桥接(见 Transformers 目录);Scalar.AspNetCore.Swashbuckle:为 Swashbuckle 生态提供对应的 OperationFilter 实现(见 Filters 目录)。
三套实现共享同一套面向用户的特性(Attributes)与配置入口,保证无论你使用哪种 OpenAPI 生成方案,都能获得一致的 Scalar 渲染体验。
二、快速开始:MapScalarApiReference 与默认端点
2.1 最小的接入代码
在完成dotnet add package Scalar.AspNetCore并配置好 OpenAPI 文档生成后,只需在管道中注册端点:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddOpenApi(); var app = builder.Build(); app.MapOpenApi(); app.MapScalarApiReference(); app.Run();启动后访问/scalar(注意末尾斜杠),即可看到渲染出的 API Reference 页面。
2.2 默认行为背后的源码实现
阅读 ScalarEndpointRouteBuilderExtensions.cs 可以确认几个关键默认行为:
- 默认端点前缀为
/scalar,通过DefaultEndpointPrefix常量定义; - 自动重定向:
ShouldRedirectToTrailingSlash逻辑会把/scalar重定向到/scalar/,以保证相对资源路径(JS、favicon 等)正确解析; - 文档名路由参数:端点模板为
/{documentName?},因此浏览器中直接访问/scalar/v1可以按文档名渲染对应文档;源码中会清空现有文档列表并只注入路径中指定的文档; - 默认文档回退:若既没有显式注册文档、也没有通过路由传入文档名,则自动
AddDocument("v1")作为兜底; - 端点前缀校验:
endpointPrefix不允许包含{documentName}占位符,否则抛出ArgumentException,因为该占位符被保留给路由参数使用。
2.3 同步与异步配置的重载矩阵
从 CHANGELOG 2.17.0 开始(对应 PR #9928),MapScalarApiReference新增了async 参数重载,使得可以使用异步服务来配置选项。结合源码可以看到当前提供的能力矩阵:
| 配置签名 | 说明 |
|---|---|
Action<ScalarOptions> | 同步配置选项 |
Func<ScalarOptions, Task> | 异步配置选项(2.17.0+) |
Action<ScalarOptions, HttpContext> | 同步配置并注入 HttpContext |
Func<ScalarOptions, HttpContext, Task> | 异步配置并注入 HttpContext(2.17.0+) |
其中HttpContext注入能力是在 2.0.0 引入的,它允许在配置时访问当前请求上下文(例如动态读取 Host、PathBase 以构造 baseServerUrl,这正是 2.1.1 “Dynamic baseServerUrl” 特性的实现基础)。
三、核心能力演进时间线
CHANGELOG 记录了这个包的完整演进史,下面按主题而非时间顺序整理出对开发者最有价值的里程碑:
| 版本 | 关键能力 |
|---|---|
| 2.0.0 | 大版本重构:EndpointPathPrefix废弃、引入endpointPrefix参数、子路径部署自动处理、HttpContext 注入、/scalar自动重定向、静态资源缓存与 ETag、[StringSyntax]注解、Metadata拼写修复为MetaData |
| 2.1.0 | 支持多个 OpenAPI 文档(同时提供配套文档) |
| 2.1.2 | 支持为每个文档配置自定义路由模式 |
| 2.2.0 | 全新的认证配置体系(HTTP、OAuth2、API Key) |
| 2.3.0 | 多首选安全方案、自定义 JS 配置模块 |
| 2.3.1 | 内嵌资源 GZip 压缩 |
| 2.4.0 | 持久化认证状态(浏览器 LocalStorage) |
| 2.4.5 | 代码示例(code samples)与AdditionalQueryParameters |
| 2.5.0 | DocumentDownloadType配置,HideDownloadButton标记过时 |
| 2.7.0 | .NET 10目标支持、x-badges扩展 |
| 2.8.4 | SchemaPropertyOrder与OrderRequiredPropertiesFirst |
| 2.8.5 | 直接下载类型、ETag 头生成优化 |
| 2.9.0 | ScalarOptions 的全新扩展方法体系 |
| 2.10.0 | 提取共享 .NET 代码(@scalar/dotnet-shared) |
| 2.11.0 | 完整 .NET 10 支持、showDeveloperTools、telemetry 选项 |
| 2.13.19 | MCP 禁用配置支持 |
| 2.14.0 | DeprecatedAttribute标记弃用端点 |
| 2.15.0 | 脚本标签的加密 nonce(CSP 支持) |
| 2.16.0 | AsyncAPI 文档支持 |
| 2.16.11 | 托管无关的 HTML/静态资源渲染核心提取到共享项目 |
| 2.17.0 | MapScalarApiReference 异步参数重载 |
四、多 OpenAPI 文档与 API 版本化
多文档支持(2.1.0)是该包最具代表性的能力之一,官方配套文档位于 integrations/dotnet/aspnetcore/docs/multiple-openapi-documents.md。
4.1 为每个 API 版本生成独立文档
使用Microsoft.AspNetCore.Mvc.Versioning时,典型做法是为每个版本单独注册 OpenAPI 文档:
string[] versions = ["v1", "v2"]; foreach (var version in versions) { builder.Services.AddOpenApi(version, options => { // 向文档写入版本信息 options.AddDocumentTransformer((document, context, _) => { var descriptionProvider = context.ApplicationServices.GetRequiredService<IApiVersionDescriptionProvider>(); var versionDescription = descriptionProvider.ApiVersionDescriptions.FirstOrDefault(x => x.GroupName == version); document.Info.Version = versionDescription?.ApiVersion.ToString(); return Task.CompletedTask; }); // 标记已弃用的 API options.AddOperationTransformer((operation, context, _) => { var apiDescription = context.Description; operation.Deprecated = apiDescription.IsDeprecated(); return Task.CompletedTask; }); }); }4.2 在 Scalar 中注册多个文档
ScalarOptions提供了AddDocument/AddDocuments系列方法,支持四种注册方式:
方式一:AddDocument 逐个注册
app.MapScalarApiReference(options => { // 默认路由模式 /openapi/{documentName}.json,只需文档名 options.AddDocument("v1"); // 跳过标题,仅指定 routePattern options.AddDocument("v2", routePattern: "/api-docs/{documentName}/spec.json"); // 全部参数指定 options.AddDocument("v3", "Version 3.0", "/api-documentation/v3.json"); // 外部文档地址 options.AddDocument("external", routePattern: "https://api.example.com/v1/openapi.json"); });方式二:AddDocuments 批量注册
string[] versions = ["v1", "v2", "v3"]; app.MapScalarApiReference(options => { options.AddDocuments(versions); // 或者可变参数写法 options.AddDocuments("v4", "v5", "v6"); });方式三:AddDocuments + ScalarDocument 对象
var documents = [ new ScalarDocument("v1", "Production API", "api/v1/spec.json"), new ScalarDocument("v2-beta", "Beta API", "beta/openapi.json"), new ScalarDocument("v3-dev", "Development API", "dev/specs/{documentName}.json") ]; app.MapScalarApiReference(options => options.AddDocuments(documents));方式四:Options 模式
builder.Services.Configure<ScalarOptions>(options => { options .AddDocument("v1", "Production API") .AddDocument("v2-beta", "Beta API", "beta/openapi.json"); });routePattern支持{documentName}占位符,未指定时使用ScalarOptions.OpenApiRoutePattern的默认模式。配置完成后,Scalar 界面会出现版本选择器,用户可在不同 API 版本文档间切换。这一能力与 2.12.0 中移除过时的EndpointPathPrefix属性一脉相承——文档的路由现在完全由routePattern统一控制。
五、AsyncAPI 支持:文档类型的横向扩展
CHANGELOG 2.16.0(PR #9413)引入了AsyncAPI 文档支持,这是该包从“仅 OpenAPI”走向“多规范文档”的关键一步。它新增了三个 API:
AddAsyncApiDocument:注册单个 AsyncAPI 文档;AddAsyncApiDocuments:批量注册;WithAsyncApiRoutePattern:自定义 AsyncAPI 文档的服务路由。
AsyncAPI 文档使用独立于 OpenAPI 的默认路由模式/asyncapi/{documentName}.json,并且该路由是在配置阶段惰性解析的。这意味着你可以把事件驱动的 API 契约(AsyncAPI 描述)与请求/响应型 API(OpenAPI 描述)注册在同一个 Scalar API Reference 中统一呈现。
从 2.16.11(PR #9620)的变更可以看出其架构取向:该版本把“托管无关的 HTML/静态资源渲染核心”提取到了共享项目(@scalar/dotnet-shared),使同一套渲染内核可以被 ASP.NET Core、Azure Functions、AWS Lambda 等不同 .NET 托管环境复用,且对Scalar.AspNetCore无公共 API 和行为变更。
六、认证配置体系
Scalar 渲染的认证选项完全来源于 OpenAPI 文档中的安全方案定义——仅在 DI 中注册认证服务并不会自动写入 OpenAPI 文档。完整讲解见 integrations/dotnet/aspnetcore/docs/authentication.md。
6.1 通过 DocumentTransformer 注入安全方案
以 JWT Bearer 为例,需要在AddOpenApi的配置中注册OpenApiDocumentTransformer:
options.AddDocumentTransformer((document, _, _) => { var securityScheme = new OpenApiSecurityScheme { Type = SecuritySchemeType.Http, In = ParameterLocation.Header, Scheme = "bearer" }; document.Components ??= new OpenApiComponents(); document.Components.SecuritySchemes.Add(JwtBearerDefaults.AuthenticationScheme, securityScheme); return Task.CompletedTask; });如需全局强制执行该安全方案,可追加document.SecurityRequirements:
var referenceScheme = new OpenApiSecurityScheme { Reference = new OpenApiReference { Id = JwtBearerDefaults.AuthenticationScheme, Type = ReferenceType.SecurityScheme } }; document.SecurityRequirements.Add(new OpenApiSecurityRequirement { [referenceScheme] = [] });6.2 在 Scalar 侧预配置认证
CHANGELOG 2.2.0 开始引入全新的认证配置扩展方法体系(2.4.8 又补充了认证扩展方法并优化了 mapper 性能),核心方法是AddPreferredSecuritySchemes+ 各类型认证配置:
app.MapScalarApiReference(options => options .AddPreferredSecuritySchemes("BearerAuth") .AddHttpAuthentication("BearerAuth", auth => { auth.Token = "ey..."; }) .WithPersistentAuthentication() // 刷新页面后保持认证状态 );各认证类型的配置入口汇总:
| 认证类型 | 扩展方法 | 常用配置项 |
|---|---|---|
| HTTP Bearer | AddHttpAuthentication | Token |
| HTTP Basic | AddHttpAuthentication | Username、Password |
| API Key | AddApiKeyAuthentication | Value |
| OAuth2 客户端凭证 | AddClientCredentialsFlow | ClientId、ClientSecret、SelectedScopes |
| OAuth2 授权码 | AddAuthorizationCodeFlow | ClientId、ClientSecret、Pkce(如Pkce.Sha256) |
| OAuth2 隐式 | AddImplicitFlow | ClientId |
| OAuth2 密码 | AddPasswordFlow | ClientId、Username、Password |
| OAuth2 多流程 | AddOAuth2Flows | 各 Flow 对象 +AddDefaultScopes |
注意:AddClientCredentialsFlow、AddAuthorizationCodeFlow、AddImplicitFlow、AddPasswordFlow和AddOAuth2Flows都是对核心方法AddOAuth2Authentication的便捷封装,后者的ScalarFlows模型支持同时声明 AuthorizationCode 与 ClientCredentials 等多项流程,并可覆盖 OpenAPI 文档中的TokenUrl、AuthorizationUrl、RedirectUri。多个安全方案可并行注册(如同时配置 OAuth 与 ApiKey),并可用AddPreferredSecuritySchemes("OAuth", "ApiKey")指定多个首选方案(该能力来自 2.3.0)。
官方文档明确警告:预填充的认证信息会暴露给客户端/浏览器,存在安全风险,请勿在生产环境使用。
七、子路径部署与端点定制
7.1 2.0.0 的大版本重构
2.0.0 是迁移影响最大的一个版本,其变更集中解决“把 API 文档部署在子路径下”的场景:
EndpointPathPrefix属性被标记过时并最终在 2.12.0 移除,取而代之的是MapScalarApiReference的endpointPrefix参数;- 子路径部署实现自动处理,不再需要手动 workaround;
/scalar自动重定向到/scalar/,保证相对路径资源解析正确;- 静态资源引入缓存与 ETag 头;
- 大量
[StringSyntax]注解改善 IDE 开发体验; - 修复
Metadata→MetaData的拼写错误,配置恢复正常工作。
配套的迁移说明与子路径部署细节可查看 integrations/dotnet/aspnetcore/docs/subpath-deployment.md。
7.2 自定义端点前缀
app.MapScalarApiReference("/api-docs", options => { options.AddDocument("v1"); });端点前缀参数带有[StringSyntax("Route")]注解(对应 CHANGELOG 1.2.28 的改进),编译器会校验路由语法。如前述源码所示,前缀中不能包含{documentName}。
八、静态资源服务:GZip、ETag 与缓存控制
静态资源(scalar.js、scalar.aspnetcore.js、favicon.svg)以内嵌资源形式随包分发,其服务逻辑在 ScalarEndpointRouteBuilderExtensions.cs 的HandleStaticAsset方法中实现:
- GZip 协商压缩:2.3.1 引入 GZip 压缩内嵌资源,2.4.0 又优化了 GZip 检查逻辑;服务时根据请求的
Accept-Encoding头选择压缩版本(IsGzipAccepted()); - ETag 与 304:静态资源带 ETag,客户端携带匹配的
If-None-Match时返回304 Not Modified(2.8.5 优化了 ETag 头生成); - 缓存策略:响应头设置
Cache-Control: no-cache,同时通过Vary: Accept-Encoding避免代理缓存错乱; - 404 兜底:若内嵌资源缺失(理论上不会发生),返回 404。
CHANGELOG 中还记录了相关性能优化:1.2.10 改为使用打包的 JS 资产(移除外部资源引用)、2.7.3 修复脚本加载性能问题、2.4.8 优化配置映射器性能。
九、安全增强:CSP Nonce 与 MCP 配置
9.1 CSP 脚本 nonce(2.15.0)
2.15.0(PR #9240)为脚本标签引入加密 nonce支持,用于满足 Content-Security-Policy 严格脚本策略:
app.MapScalarApiReference(options => options .WithNonce() // 每次请求自动生成 );WithNonce()无参数重载会为每个请求自动生成一次性 nonce;也可以手动传入固定值。从源码实现可以看到配套的安全处理:
- 设置了 nonce 时,响应头写入
Cache-Control: no-store,防止中间层或浏览器把一次性 nonce 重放给其他客户端; - nonce 通过
HttpContext.Items传递,最终注入渲染的 HTML。
9.2 MCP 与遥测配置
2.13.19(PR #8640)为 Aspire 与 AspNetCore 集成都增加了MCP 禁用配置支持,使得在企业环境无法连接外部 MCP 服务时也能正常渲染文档。2.11.0 则增加了showDeveloperTools与 telemetry 选项,让开发者可以控制开发者工具面板的显隐以及遥测数据的开关。
十、端点元数据与扩展点
10.1 面向源码的特性体系
Scalar.AspNetCore核心包提供了声明式特性(见 Attributes 目录),并在Microsoft与Swashbuckle两个包中分别以 Transformer / OperationFilter 形式落地:
| 特性 | 作用 | 对应版本 |
|---|---|---|
DeprecatedAttribute | 将端点标记为已弃用 | 2.14.0 |
CodeSampleAttribute | 为操作附加自定义代码示例 | 2.4.5 引入代码示例支持 |
BadgeAttribute | 渲染徽章(x-badges扩展) | 2.7.0 |
StabilityAttribute | 标记接口稳定性状态 | 与 Converters/Enums 配套 |
ExcludeFromApiReferenceAttribute | 从 API Reference 中排除端点/文档 | — |
例如 DeprecatedAttribute.cs 在 Microsoft 生态中由 DeprecatedOpenApiOperationTransformer.cs 消费,在 Swashbuckle 生态中由 DeprecatedEndpointFilter.cs 消费——同一特性、双生态落地。
10.2 更多 OpenAPI 扩展支持
CHANGELOG 记录了持续吸收 OpenAPI 生态扩展点的过程:x-scalar-credentials-location(2.6.5)、x-scalar-security-body(2.6.2)、x-tokenName(2.6.0)、x-order(依赖升级中随 api-reference 引入)等,使 OpenAPI 文档可以携带更丰富的展示语义,Scalar 渲染端则一一识别呈现。
十一、工程化演进:共享代码、AOT 与迁移注意
11.1 dotnet-shared 共享架构
2.10.0 开始使用共享 .NET 代码(@scalar/dotnet-shared),2.16.11 把 HTML/静态资源渲染核心完整提取到共享项目,使 ASP.NET Core、Azure Functions、AWS Lambda(见 integrations/dotnet 下的 aws-lambda 与 azure-functions 目录)等托管方式共享同一渲染内核。
11.2 AOT 兼容性
2.0.2 修复了Regex 在 AOT 环境下的问题,2.0.3 修复匿名资源端点,2.0.4 修复HiddenClients行为,说明该包从 2.0 起就关注 Native AOT 场景下的可用性。2.1.2 则支持为每个文档配置自定义 pattern。
11.3 升级迁移清单
基于 2.0.0 与 2.12.0 的破坏性变更,从旧版本升级时请注意:
- 移除
EndpointPathPrefix属性用法,改用endpointPrefix参数或routePattern; - 若此前为了子路径部署写过 workaround,需删除并验证自动处理是否生效;
- 涉及
Metadata属性的配置需改为MetaData; - 若使用
HideDownloadButton,迁移到DocumentDownloadType(2.5.0 引入,原属性标记过时)。
十二、总结
从 1.2 到 2.17,Scalar.AspNetCore 的演进主线清晰可见:以 OpenAPI 文档为单一事实来源,逐步补齐多文档/多规范(OpenAPI + AsyncAPI)、认证预配置、子路径部署、静态资源性能、安全(CSP nonce)与企业级配置(MCP/telemetry)等能力,同时通过共享 .NET 渲染内核保持跨托管环境的一致性。对 .NET 开发者而言,这套集成意味着可以用极少的样板代码,把 API 文档从“静态页面”升级为“可交互、可认证、可切换版本”的一等公民。
如需进一步深入,推荐按以下路径阅读仓库:
- 集成包能力全貌:integrations/dotnet/aspnetcore/README.md
- 完整演进记录:integrations/dotnet/aspnetcore/CHANGELOG.md
- 多文档实战:integrations/dotnet/aspnetcore/docs/multiple-openapi-documents.md
- 认证配置详解:integrations/dotnet/aspnetcore/docs/authentication.md
- 子路径部署:integrations/dotnet/aspnetcore/docs/subpath-deployment.md
- 核心实现:ScalarEndpointRouteBuilderExtensions.cs
【免费下载链接】scalarScalar is an open-source API platform: 🌐 Modern REST API Client 📖 Beautiful API References ✨ 1st-Class OpenAPI/Swagger Support项目地址: https://gitcode.com/GitHub_Trending/sc/scalar
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考