Backend Development 10 min read

Including NuGet Package XML Documentation in Swagger for .NET Core Projects with Docker CI/CD

This article explains how to configure .NET Core projects and Docker build pipelines so that XML documentation files from reusable NuGet packages are correctly copied and displayed in Swagger UI, covering project file changes, MSBuild targets, Dockerfile adjustments, and environment variables.

Fulu Network R&D Team
Fulu Network R&D Team
Fulu Network R&D Team
Including NuGet Package XML Documentation in Swagger for .NET Core Projects with Docker CI/CD

When developing .NET Core applications, reusable components are often packaged as NuGet libraries. While code reuse works fine, the XML documentation needed by Swashbuckle to show controller and model comments does not appear for types defined in those packages.

The solution consists of several steps:

1. Enable XML documentation generation in the NuGet package project

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

This adds the *.xml file to the package output.

2. Declare the XML files as content to be copied from the package

<PackageReference Include="ICH.Common" Version="$(ICHCoreFXVersion)">
  <CopyToOutputDirectory>lib\netstandard2.0\*.xml</CopyToOutputDirectory>
</PackageReference>

The relative path points to the XML file inside the NuGet package.

3. Add an MSBuild target that copies the XML files after a normal build

<Target Name="AfterTargetsBuild" AfterTargets="Build">
  <ItemGroup>
    <PackageReferenceFiles Condition="%(PackageReference.CopyToOutputDirectory) != ''" 
                         Include="$(NugetPackageRoot)\%(PackageReference.Identity)\%(PackageReference.Version)\%(PackageReference.CopyToOutputDirectory)" />
  </ItemGroup>
  <Copy SourceFiles="@(PackageReferenceFiles)" DestinationFolder="$(OutDir)" />
</Target>

This ensures the XML files are present in the build output directory.

4. Add a similar target for the publish step

<Target Name="AfterTargetsPublish" AfterTargets="Publish">
  <ItemGroup>
    <PackageReferenceFiles Condition="%(PackageReference.CopyToOutputDirectory) != ''" 
                         Include="$(NugetPackageRoot)\%(PackageReference.Identity)\%(PackageReference.Version)\%(PackageReference.CopyToOutputDirectory)" />
  </ItemGroup>
  <Copy SourceFiles="@(PackageReferenceFiles)" DestinationFolder="$(PublishDir)" />
</Target>

This copies the XML files into the publish folder used by Docker.

5. Register the XML files with Swashbuckle

public static void ConfigureSwagger(this IServiceCollection services)
{
    var xmlFiles = Directory.GetFiles(AppContext.BaseDirectory, "*.xml");
    foreach (var xmlFile in xmlFiles)
        options.IncludeXmlComments(xmlFile, true);
}

All XML files found in the output directory are added to the Swagger definition.

6. Docker considerations

In Docker builds the XML files were missing because the NuGet CLI defaulted to compressing documentation files. Setting the environment variable NUGET_XMLDOC_MODE to none forces NuGet to treat XML docs as regular files:

ENV NUGET_XMLDOC_MODE none

After this change the XML files appear in the container’s package cache, but the copy targets still need the correct case‑sensitive path. Converting %(PackageReference.Identity) to lower case resolves the mismatch on Linux.

7. Final verification

Rebuilding and publishing the Docker image now places ICH.Common.xml in the output folder, and Swagger UI correctly displays the model documentation from the NuGet package. The article concludes with the full .csproj and Dockerfile contents for reference.

dockerCI/CDSwagger.NET CoreNuGetXML Documentation
Fulu Network R&D Team
Written by

Fulu Network R&D Team

Providing technical literature sharing for Fulu Holdings' tech elite, promoting its technologies through experience summaries, technology consolidation, and innovation sharing.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.