深入解读 Scalar.AspNetCore:ASP.NET Core 集成从 1.2 到 2.17 的能力演进与实战指南
2026/9/14 11:59:28 网站建设 项目流程

深入解读 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.0DocumentDownloadType配置,HideDownloadButton标记过时
2.7.0.NET 10目标支持、x-badges扩展
2.8.4SchemaPropertyOrderOrderRequiredPropertiesFirst
2.8.5直接下载类型、ETag 头生成优化
2.9.0ScalarOptions 的全新扩展方法体系
2.10.0提取共享 .NET 代码(@scalar/dotnet-shared
2.11.0完整 .NET 10 支持、showDeveloperTools、telemetry 选项
2.13.19MCP 禁用配置支持
2.14.0DeprecatedAttribute标记弃用端点
2.15.0脚本标签的加密 nonce(CSP 支持)
2.16.0AsyncAPI 文档支持
2.16.11托管无关的 HTML/静态资源渲染核心提取到共享项目
2.17.0MapScalarApiReference 异步参数重载

四、多 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 BearerAddHttpAuthenticationToken
HTTP BasicAddHttpAuthenticationUsernamePassword
API KeyAddApiKeyAuthenticationValue
OAuth2 客户端凭证AddClientCredentialsFlowClientIdClientSecretSelectedScopes
OAuth2 授权码AddAuthorizationCodeFlowClientIdClientSecretPkce(如Pkce.Sha256
OAuth2 隐式AddImplicitFlowClientId
OAuth2 密码AddPasswordFlowClientIdUsernamePassword
OAuth2 多流程AddOAuth2Flows各 Flow 对象 +AddDefaultScopes

注意:AddClientCredentialsFlowAddAuthorizationCodeFlowAddImplicitFlowAddPasswordFlowAddOAuth2Flows都是对核心方法AddOAuth2Authentication的便捷封装,后者的ScalarFlows模型支持同时声明 AuthorizationCode 与 ClientCredentials 等多项流程,并可覆盖 OpenAPI 文档中的TokenUrlAuthorizationUrlRedirectUri。多个安全方案可并行注册(如同时配置 OAuth 与 ApiKey),并可用AddPreferredSecuritySchemes("OAuth", "ApiKey")指定多个首选方案(该能力来自 2.3.0)。

官方文档明确警告:预填充的认证信息会暴露给客户端/浏览器,存在安全风险,请勿在生产环境使用

七、子路径部署与端点定制

7.1 2.0.0 的大版本重构

2.0.0 是迁移影响最大的一个版本,其变更集中解决“把 API 文档部署在子路径下”的场景:

  • EndpointPathPrefix属性被标记过时并最终在 2.12.0 移除,取而代之的是MapScalarApiReferenceendpointPrefix参数;
  • 子路径部署实现自动处理,不再需要手动 workaround;
  • /scalar自动重定向到/scalar/,保证相对路径资源解析正确;
  • 静态资源引入缓存与 ETag 头
  • 大量[StringSyntax]注解改善 IDE 开发体验;
  • 修复MetadataMetaData的拼写错误,配置恢复正常工作。

配套的迁移说明与子路径部署细节可查看 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.jsscalar.aspnetcore.jsfavicon.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 目录),并在MicrosoftSwashbuckle两个包中分别以 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 的破坏性变更,从旧版本升级时请注意:

  1. 移除EndpointPathPrefix属性用法,改用endpointPrefix参数或routePattern
  2. 若此前为了子路径部署写过 workaround,需删除并验证自动处理是否生效;
  3. 涉及Metadata属性的配置需改为MetaData
  4. 若使用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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询