mcpField
D
dotnet-api-docs

dotnet-api-docs

github.com/wshaddix开发8677 次安装35 周前更新
代码仓库

关于 dotnet-api-docs

面向 .NET 项目的 API 文档生成技能,涵盖 DocFX 参考文档与 OpenAPI 交互式文档,并提供同步校验和版本维护实践。

主要功能

  1. 01从程序集生成 DocFX API 参考
  2. 02定制模板与页面交叉引用
  3. 03嵌入 Scalar 或 Swagger UI
  4. 04校验文档完整性与链接
  5. 05维护版本文档和迁移指南

适用场景

  1. 01为 .NET 库构建 API 参考站点
  2. 02将 OpenAPI 规范呈现为交互文档
  3. 03在 CI 中发现缺失注释和断链

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/wshaddix/dotnet-skills --skill dotnet-api-docs

安装后在 Claude Code 中输入/dotnet-api-docs确认已加载。

详细介绍

dotnet-api-docs

为 .NET 项目生成 API 文档:配置 DocFX,从程序集生成 API 参考(docfx.json 配置、元数据提取、模板自定义、交叉引用),将 OpenAPI 规范用作实时 API 文档(嵌入 Scalar 和 Swagger UI、版本化 OpenAPI 文档),同步文档与代码(通过 -warnaserror:CS1591 在 CI 中验证、检测失效链接、在 PR 上自动构建文档),API 更新日志模式(记录重大变更、迁移指南、跟踪已弃用的 API),以及版本化 API 文档(版本选择器、多版本维护、URL 模式)。

版本假设: DocFX v2.x(由社区维护)。通过 Microsoft.AspNetCore.OpenApi 使用 OpenAPI 3.x(.NET 9+ 内置)。使用 Scalar UI 展示现代 OpenAPI。代码示例以 .NET 8.0+ 为基准。

范围边界: 此技能负责从代码生成 API 文档,包括将源代码、XML 注释和 OpenAPI 规范转换为可浏览文档的工具和流程。XML 文档注释语法和编写规范由 [skill:dotnet-xml-docs] 负责。OpenAPI 规范生成和 Swashbuckle 迁移由 [skill:dotnet-openapi] 负责。文档站点的 CI/CD 部署由 [skill:dotnet-gha-deploy] 负责。文档平台的选择(Starlight、DocFX 或 Docusaurus)由 [skill:dotnet-documentation-strategy] 负责。

范围之外: XML 文档注释语法和编写——参见 [skill:dotnet-xml-docs]。OpenAPI 规范生成和配置(Swashbuckle、Microsoft.AspNetCore.OpenApi 设置)——参见 [skill:dotnet-openapi]。文档站点的 CI/CD 部署流水线——参见 [skill:dotnet-gha-deploy]。文档平台选择和初始设置——参见 [skill:dotnet-documentation-strategy]。更新日志生成工具和 SemVer 版本管理——参见 [skill:dotnet-release-management]。

交叉引用:[skill:dotnet-xml-docs](XML 文档注释编写)、[skill:dotnet-openapi](OpenAPI 生成)、[skill:dotnet-gha-deploy](文档站点部署流水线)、[skill:dotnet-documentation-strategy](平台选择)、[skill:dotnet-release-management](更新日志工具和版本管理)。


为 .NET API 参考配置 DocFX

DocFX 直接从 .NET 程序集和 XML 文档注释生成 API 参考文档。它是唯一支持从 .NET 项目原生运行 docfx metadata 提取元数据的文档工具。

安装
# Install DocFX as a .NET global tool
dotnet tool install -g docfx

# Or as a local tool (recommended for team consistency)
dotnet new tool-manifest
dotnet tool install docfx
配置(docfx.json)
{
  "metadata": [
    {
      "src": [
        {
          "files": ["src/**/*.csproj"],
          "exclude": ["**/bin/**", "**/obj/**"],
          "src": ".."
        }
      ],
      "dest": "api",
      "properties": {
        "TargetFramework": "net8.0"
      },
      "disableGitFeatures": false,
      "disableDefaultFilter": false
    }
  ],
  "build": {
    "content": [
      {
        "files": ["api/**.yml", "api/index.md"]
      },
      {
        "files": [
          "articles/**.md",
          "articles/**/toc.yml",
          "toc.yml",
          "*.md"
        ]
      }
    ],
    "resource": [
      {
        "files": ["images/**"]
      }
    ],
    "dest": "_site",
    "globalMetadataFiles": [],
    "fileMetadataFiles": [],
    "template": ["default", "modern"],
    "postProcessors": ["ExtractSearchIndex"],
    "markdownEngineName": "markdig",
    "noLangKeyword": false,
    "keepFileLink": false,
    "cleanupCacheHistory": false,
    "disableGitFeatures": false,
    "globalMetadata": {
      "_appTitle": "My.Library API Reference",
      "_appFooter": "Copyright 2024 My Company",
      "_enableSearch": true,
      "_enableNewTab": true
    }
  }
}
元数据提取

metadata 部分控制 DocFX 如何从 .NET 项目中提取 API 信息:

# Generate API metadata YAML files from projects
docfx metadata docfx.json

# This creates YAML files in the api/ directory:
#   api/MyLibrary.WidgetService.yml
#   api/MyLibrary.Widget.yml
#   api/toc.yml

主要元数据配置选项:

属性用途默认值
src.files要从中提取的项目文件必填
destYAML 输出目录api
properties.TargetFramework要针对其进行构建的 TFM项目默认值
disableGitFeatures跳过 Git blame 信息false
filterAPI 筛选 YAML 文件的路径无(所有公共 API)
API 筛选

从生成的文档中排除内部类型:

# filterConfig.yml
apiRules:
  - exclude:
      uidRegex: ^MyLibrary\.Internal\.
      type: Namespace
  - exclude:
      hasAttribute:
          uid: System.ComponentModel.EditorBrowsableAttribute
          ctorArguments:
            - System.ComponentModel.EditorBrowsableState.Never

在 docfx.json 中引用筛选文件:

{
  "metadata": [
    {
      "filter": "filterConfig.yml"
    }
  ]
}
自定义模板

DocFX 支持通过覆盖模板自定义品牌样式:

docs/
  templates/
    custom/
      styles/
        main.css          # Custom CSS overrides
      partials/
        head.tmpl.partial # Custom head section (analytics, fonts)
        footer.tmpl.partial

在 docfx.json 中引用自定义模板:

{
  "build": {
    "template": ["default", "modern", "templates/custom"]
  }
}
页面间交叉引用

DocFX 支持在 API 页面和概念性文章之间使用基于 uid 的交叉引用:


See the @MyLibrary.WidgetService.CreateWidgetAsync(System.String) method for details.

For the full API, see <xref:MyLibrary.WidgetService>.
# In an API YAML override file (api/MyLibrary.WidgetService.yml)
# Add links to conceptual articles
references:
  - uid: MyLibrary.WidgetService
    seealso:
      - linkId: ../articles/getting-started.md
        commentId: getting-started

将 OpenAPI 规范用作文档

生成的 OpenAPI 规范可作为与代码保持同步的实时 API 文档。本节介绍如何将 OpenAPI 输出用作文档;有关 OpenAPI 的生成和配置,请参见 [skill:dotnet-openapi]。

Scalar UI 嵌入

Scalar 提供现代化的交互式 API 文档查看器:

// Program.cs
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenApi();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();         // Serves OpenAPI JSON at /openapi/v1.json
    app.MapScalarApiReference(options =>
    {
        options.WithTitle("My API Documentation")
               .WithTheme(ScalarTheme.Purple)
               .WithDefaultHttpClient(ScalarTarget.CSharp, ScalarClient.HttpClient);
    });
}

app.Run();

Scalar 会将 OpenAPI 规范呈现为交互式文档页面,其中包含:

  • 按标签对端点分组
  • 请求/响应示例
  • 身份验证配置
  • 用于测试端点的“试用”功能
Swagger UI 嵌入

对于使用 Swashbuckle 或需要经典 Swagger UI 的项目:

if (app.Environment.IsDevelopment())
{
    app.UseSwaggerUI(options =>
    {
        options.SwaggerEndpoint("/openapi/v1.json", "My API v1");
        options.RoutePrefix = "api-docs";
        options.DocumentTitle = "My API Documentation";
        options.DefaultModelsExpandDepth(-1); // Hide schemas by default
    });
}
版本化 OpenAPI 文档

为不同的 API 版本提供多个 OpenAPI 文档:

builder.Services.AddOpenApi("v1", options =>
{
    options.AddDocumentTransformer((document, context, ct) =>
    {
        document.Info.Version = "1.0";
        document.Info.Title = "My API";
        return Task.CompletedTask;
    });
});

builder.Services.AddOpenApi("v2", options =>
{
    options.AddDocumentTransformer((document, context, ct) =>
    {
        document.Info.Version = "2.0";
        document.Info.Title = "My API";
        return Task.CompletedTask;
    });
});

// Serves /openapi/v1.json and /openapi/v2.json
app.MapOpenApi();
导出 OpenAPI 以生成静态文档

在构建时导出 OpenAPI 规范,以便用于静态文档站点:

# Generate OpenAPI spec from the running application
dotnet run -- --urls "http://localhost:5099" &
APP_PID=$!
sleep 3
curl -s http://localhost:5099/openapi/v1.json > docs/openapi/v1.json
kill $APP_PID

或者,使用 Microsoft.Extensions.ApiDescription.Server 包在构建时生成:

<PackageReference Include="Microsoft.Extensions.ApiDescription.Server" Version="8.0.0">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>

<PropertyGroup>
  <OpenApiGenerateDocuments>true</OpenApiGenerateDocuments>
  <OpenApiDocumentsDirectory>$(MSBuildProjectDirectory)/../docs/openapi</OpenApiDocumentsDirectory>
</PropertyGroup>

有关 OpenAPI 生成设置和 Swashbuckle 迁移详情,请参阅 [skill:dotnet-openapi]。


从 XML 注释生成文档站点

XML 文档转 DocFX(静态 HTML)

用于库 API 参考文档的主要工作流:

Source Code (.cs files)
    |
    v
XML Doc Comments (/// <summary>...)
    |
    v
Build with GenerateDocumentationFile=true
    |
    v
XML Doc File (MyLibrary.xml)
    |
    v
docfx metadata (extracts API structure)
    |
    v
YAML Files (api/*.yml)
    |
    v
docfx build (generates HTML)
    |
    v
Static HTML Site (_site/)

有关 XML 文档注释编写的最佳实践,请参阅 [skill:dotnet-xml-docs]。

XML 文档转 Starlight(通过 Markdown 提取)

对于使用 Starlight 而非 DocFX 的项目,可将 API 文档提取为 Markdown:

  1. 生成 XML 文档文件,方法是设置 <GenerateDocumentationFile>true</GenerateDocumentationFile>
  2. 使用转换工具将 XML 文档转换为 Markdown 页面:
    • xmldoc2md(社区工具):将 XML 文档文件转换为 Markdown
    • 自定义脚本:解析 XML 文件,并为每种类型生成 Markdown 页面
# Using xmldoc2md
dotnet tool install -g XMLDoc2Markdown
xmldoc2md MyLibrary.dll docs/src/content/docs/reference/

# Output: one Markdown file per type in the reference/ directory
  1. 纳入 Starlight 构建:
docs/src/content/docs/
  reference/
    MyLibrary.WidgetService.md    # Auto-generated from XML docs
    MyLibrary.Widget.md
    MyLibrary.WidgetStatus.md

配置侧边栏,使其从参考文档目录自动生成:

// astro.config.mjs
sidebar: [
  {
    label: 'API Reference',
    autogenerate: { directory: 'reference' },
  },
],

保持文档与代码同步

在 CI 中验证文档完整性

在 CI 中将 CS1591 视为错误,以强制确保 XML 文档完整:


<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>


<PropertyGroup Condition="'$(IsPublicLibrary)' == 'true'">
  <WarningsAsErrors>$(WarningsAsErrors);CS1591</WarningsAsErrors>
</PropertyGroup>
# CI command: build with warnings-as-errors for doc completeness
dotnet build -warnaserror:CS1591

如果任何公共成员缺少 XML 文档,这会导致构建失败。使用 IsPublicLibrary 条件(或按项目配置),仅将此规则应用于已发布的 NuGet 包,而不应用于测试项目或内部工具。

检测失效链接

在 CI 中验证文档链接:

# Build DocFX and check for broken cross-references
docfx build docfx.json --warningsAsErrors

# DocFX reports broken xref links as warnings -- the flag promotes them to errors

对于 Starlight 或 Docusaurus 站点,可在构建后使用链接检查器:

# Build the doc site
npm run build

# Check for broken links in the built output
npx broken-link-checker-local ./_site --recursive
在 PR 中自动构建文档

在每个拉取请求中验证文档构建,但不进行部署。有关部署工作流配置,请参阅 [skill:dotnet-gha-deploy]。验证步骤通常作为 CI 工作流的一部分运行:

# In CI: verify docs build without errors
dotnet build -warnaserror:CS1591          # XML doc completeness
docfx metadata docfx.json                 # API metadata extraction
docfx build docfx.json --warningsAsErrors # Full doc site build

这样可以在文档问题(文档缺失、交叉引用失效)进入主分支之前,发现文档回归。


API 更新日志模式

记录重大变更

使用结构化格式记录重大变更,方便使用者快速浏览:

## Breaking Changes in v3.0

### Removed APIs

| API | Replacement | Migration |
|-----|-------------|-----------|
| `WidgetService.Create(string)` | `WidgetService.CreateAsync(string, CancellationToken)` | Add `await` and `CancellationToken` parameter |
| `Widget.Name` setter | `WidgetService.RenameAsync(Guid, string)` | Use service method instead of direct property mutation |
| `IWidgetRepository` (interface) | `IWidgetRepository<T>` (generic) | Update implementations to use generic interface |

### Changed Behavior

- `WidgetService.CreateAsync` now validates name uniqueness within a category.
  Previously, duplicate names were silently allowed.
- `Widget.Status` defaults to `Draft` instead of `Active`.
  Existing code that assumes newly created widgets are active must call `widget.Activate()`.

### New Required Dependencies

- `Microsoft.Extensions.Caching.Memory` is now a required dependency for `WidgetService`.
  Register with `builder.Services.AddMemoryCache()`.
主要版本之间的迁移指南

按所需执行的操作组织迁移指南:

# Migrating from v2.x to v3.0

## Step 1: Update Package References

```xml

<PackageReference Include="My.Library" Version="2.*" />


<PackageReference Include="My.Library" Version="3.0.0" />

步骤 2:修复编译错误

异步 API 变更

所有同步方法均已移除。请将同步调用替换为对应的异步调用:

// Before (v2.x)
var widget = service.Create("name");

// After (v3.0)
var widget = await service.CreateAsync("name", cancellationToken);
泛型仓储接口
// Before (v2.x)
public class MyRepo : IWidgetRepository { }

// After (v3.0)
public class MyRepo : IWidgetRepository<Widget> { }

步骤 3:更新行为假设

  • 检查所有假定创建后 Widget.Status == Active 的代码路径
  • 将 builder.Services.AddMemoryCache() 添加到 DI 注册中

### Deprecated API Tracking

Use the `[Obsolete]` attribute with message pointing to the replacement. Document deprecation timelines:

```csharp
/// <summary>
/// Creates a widget synchronously.
/// </summary>
/// <remarks>
/// This method will be removed in v4.0. Use
/// <see cref="CreateAsync(string, CancellationToken)"/> instead.
/// </remarks>
[Obsolete("Use CreateAsync instead. This method will be removed in v4.0.", error: false)]
public Widget Create(string name)
{
}

在专门的文档中跟踪已弃用的 API:

# Deprecated APIs

| API | Deprecated In | Removed In | Replacement |
|-----|---------------|------------|-------------|
| `WidgetService.Create(string)` | v2.5 | v4.0 (planned) | `CreateAsync(string, CancellationToken)` |
| `Widget.Name` setter | v3.0 | v4.0 (planned) | `WidgetService.RenameAsync(Guid, string)` |
| `WidgetOptions.EnableCache` | v3.1 | v5.0 (planned) | `WidgetOptions.CachePolicy` |

有关更新日志格式约定和 SemVer 版本控制策略,请参阅 [skill:dotnet-release-management]。


版本化 API 文档

文档站点中的版本选择器

DocFX 版本化文档:

DocFX 支持通过指定不同的项目版本来提取特定版本的元数据:

{
  "metadata": [
    {
      "src": [{ "files": ["src/**/*.csproj"], "src": ".." }],
      "dest": "api/v2",
      "properties": { "TargetFramework": "net8.0" },
      "globalNamespaceId": "v2"
    }
  ]
}

为每个主版本维护单独的分支或标签,并从各自的分支或标签构建文档:

# Build docs for v2.x (current branch)
docfx build docfx.json

# Build docs for v1.x (from tag)
git checkout v1.x
docfx build docfx.json --output _site/v1
git checkout main

Starlight 版本化文档:

使用基于目录的版本管理,或使用 @lorenzo_lewis/starlight-utils 插件。有关 Starlight 版本管理的设置,请参阅 [skill:dotnet-documentation-strategy]。

Docusaurus 版本化文档:

Docusaurus 内置了版本管理功能,可使用 npx docusaurus docs:version。有关 Docusaurus 版本管理的设置,请参阅 [skill:dotnet-documentation-strategy]。

维护多个活跃版本的文档

同时支持多个活跃的主版本时:

  1. 每个主版本使用一个分支的策略: 在主分支上维护 docs/v1、docs/v2 目录,或使用单独的 v1.x、v2.x 分支
  2. 共享概念性文档: 将与版本无关的指南(架构、概念)放在共享位置,并将特定版本的 API 参考放在单独的目录中
  3. 版本横幅: 在旧版本文档中添加通知横幅,指向最新版本
URL 模式

版本化 API 文档的一致 URL 模式:

https://docs.mylib.dev/                     # Latest stable version
https://docs.mylib.dev/v2/                  # Specific version
https://docs.mylib.dev/v2/api/WidgetService # Specific type in specific version
https://docs.mylib.dev/latest/              # Alias for latest stable
https://docs.mylib.dev/next/                # Pre-release / unreleased docs

配置重定向,使不带版本号的 URL 指向最新的稳定版本。这样可确保发布新版本时,现有链接仍然有效。


Agent 常见注意事项

  1. 不要生成 OpenAPI 规范配置——OpenAPI 生成设置(builder.Services.AddOpenApi()、文档转换器、Swashbuckle 迁移)属于 [skill:dotnet-openapi]。本技能涵盖如何将生成的 OpenAPI 输出用作文档。

  2. 不要编写 XML 文档注释语法指南——XML 标签语法、约定、<inheritdoc> 和 GenerateDocumentationFile 属于 [skill:dotnet-xml-docs]。本技能涵盖从 XML 文档到生成的文档站点的流程。

  3. 不要生成 CI 部署 YAML——文档站点部署工作流(GitHub Pages 操作、DocFX 部署)属于 [skill:dotnet-gha-deploy]。本技能涵盖文档构建验证和本地生成。

  4. docfx metadata 需要可构建的项目——项目必须成功编译,DocFX 才能提取 API 元数据。在 CI 流水线中,始终先运行 dotnet build,再运行 docfx metadata。

  5. 自 2022 年 11 月起,DocFX 由社区维护——Microsoft 已移交该代码库。它仍在积极维护,并得到广泛使用。对于正在评估替代方案的新项目,请参阅 [skill:dotnet-documentation-strategy]。

  6. DocFX 的 modern 模板需要 v2.75+——更早的版本使用 default 模板,该模板不支持 Mermaid,也没有现代样式。使用 docfx --version 检查已安装的版本。

  7. -warnaserror:CS1591 应仅应用于公共库项目——将它应用于测试项目、控制台应用或内部工具会造成不必要的文档负担。使用 MSBuild 条件,仅针对已发布的包。

  8. 使用 filterConfig.yml 筛选 API 时,应使用 UID 正则表达式,而非命名空间字符串——模式 ^MyLibrary\.Internal\. 匹配以该前缀开头的 UID。使用 docfx metadata --log verbose 测试筛选模式,以验证筛选是否正确。

  9. 破坏性变更文档必须包含迁移代码示例——只列出已移除 API、却不展示替代代码的表格是不够的。始终包含变更前后的代码片段。

  10. 版本化文档 URL 必须将不带版本号的路径重定向到最新稳定版本——发布新版本时,不要破坏现有链接。在根 URL 配置服务器端重定向,或添加客户端重定向页面。

  11. OpenAPI UI(Scalar、Swagger UI)应仅在开发环境中公开——将 MapScalarApiReference 和 UseSwaggerUI 放在 if (app.Environment.IsDevelopment()) 条件中。生产环境公开交互式 API 文档涉及安全问题。

评论

支持 Markdown