Sponsored
Many thanks to the sponsors who make it possible for this newsletter to be free for readers. Become a sponsor.
We know Swagger is a set of tools for developing, documenting, and consuming RESTful APIs. It helps developers design, build, document, and consume APIs more efficient.
Swashbuckle is an open-source project that integrates Swagger with .NET applications. It provides seamless support for generating Swagger documents and exposing them via a web interface in ASP.NET Core applications.
By default, when an API project is created, code is generated in Program.cs that will create the Swagger support, along with the Swagger UI.
builder.Services.AddSwaggerGen(); var app = builder.Build(); if (app.Environment.IsDevelopment()){ app.UseSwagger(); app.UseSwaggerUI();}
This UI is quite "clean" and it is possible to enrich it with many things.

I will show you 1 tip of what can be done with Swagger UI.
The IDocumentFilter interface in Swashbuckle is a powerful feature that allows you to manipulate and customize the entire Swagger/OpenAPI document before it is rendered or served to clients.
This interface provides a hook into the Swagger generation process, giving you the ability to modify, add, or remove any part of the document, such as paths, operations, schemas, and more.
Implementation
To use IDocumentFilter, you need to create a class that implements this interface and its Apply method.
The Apply method provides access to the OpenApiDocument object, which represents the entire Swagger document, and the DocumentFilterContext object, which provides additional context and information.
For example, let's create a case where you need to remove an obsolete (deprecated) endpoint from Swagger UI and not delete it from the code.
Firstly, if we tag some endpoint as obsolete, this will not hide it from Swagger UI. It will be just crossed and grayed out.

To be able to delete it, I will create RemoveObsoleteOperationsFilter implementation of IDocumentFilter abstraction.
public class RemoveObsoleteOperationsFilter : IDocumentFilter { public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) { var obsoletePaths = swaggerDoc.Paths .Where(path => path.Value.Operations .Any(op => op.Value.Deprecated)) .Select(path => path.Key) .ToList(); foreach (var obsoletePath in obsoletePaths) swaggerDoc.Paths.Remove(obsoletePath); }}
I need to add a support for this DocumentFilter. It's really to add it, just update the .AddSwaggerGen() method call in Program.cs:
builder.Services.AddSwaggerGen(c =>{ c.DocumentFilter<RemoveObsoleteOperationsFilter>();});
And now, the endpoint is removed from the Swagger UI.
Adding Global Metadata to All Operations
Adding global metadata to all operations using an IDocumentFilter allows you to enforce consistent metadata across your entire API.
This can be particularly useful for ensuring that every operation has a baseline description, common tags for categorization, or other shared metadata.
By implementing and registering a custom document filter, you can automate these modifications, making your API documentation more uniform and easier to manage.
public class AddGlobalMetadataDocumentFilter : IDocumentFilter{ public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) { foreach (var pathItem in swaggerDoc.Paths.Values) { foreach (var operation in pathItem.Operations.Values) { // Add a common description to all operations operation.Description = operation.Description ?? "This is a common description for all operations."; // Add a common tag to all operations operation.Tags = operation.Tags ?? new List<OpenApiTag>(); operation.Tags.Add(new OpenApiTag { Name = "CommonTag" }); } } }}
Result:

Adding a Custom Header to All Responses
Adding a custom header to all responses using an IDocumentFilter allows you to ensure that every API response includes specific metadata.
By implementing and registering a custom document filter, you can automate the inclusion of this header across all API endpoints, making your API documentation more comprehensive and consistent.
This approach is particularly useful for enforcing standard headers for purposes such as rate limiting, request tracking, or any other cross-cutting concerns.
public class AddCustomHeaderToResponsesDocumentFilter : IDocumentFilter{ public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) { foreach (var pathItem in swaggerDoc.Paths.Values) { foreach (var operation in pathItem.Operations.Values) { foreach (var response in operation.Responses.Values) response.Headers ??= new Dictionary<string, OpenApiHeader>(); response.Headers.Add("X-Custom-Header", new OpenApiHeader { Description = "This is a custom header added to all responses.", Schema = new OpenApiSchema { Type = "string" } }); } } } }}
Result:

In Program.cs you need to add those 2 DocumentFilters: a strategy object to perform the travel time calculation, allowing the strategy to be set dynamically.
Swagger UI itself is "clean" at the beginning of the implementation.
We often need some advanced things, such as not showing deprecated endpoints, adding metadata, adding headers, changing responses, and similar.
Fortunately, it is possible to enrich Swagger UI to such levels that it is possible to change the complete design.
The Swashbuckle Library helps us with all of this.
Using the IDocumentationFILter abstraction, we created 3 implementations:
For a deeper understanding and different implementations check out here.
You can download this source code from here.
That's all from me today.
Stop arguing about code style. In this course you get a production-proven setup with analyzers, CI quality gates, and architecture tests — the exact system I use in real projects. Join here.
Not sure yet? Grab the free Starter Kit — a drop-in setup with the essentials from Module 01.
Design Patterns that Deliver — Solve real problems with 5 battle-tested patterns (Builder, Decorator, Strategy, Adapter, Mediator) using practical, real-world examples. Trusted by 650+ developers.
Just getting started? Design Patterns Simplified covers 10 essential patterns in a beginner-friendly, 30-page guide for just $9.95.
Every Monday morning, I share 1 actionable tip on C#, .NET & Architecture that you can use right away. Join here.
Join 20,000+ subscribers who mass-improve their .NET skills with actionable tips on C#, Software Architecture & Best Practices.
Subscribe to the TheCodeMan.net and be among the 20,000+ subscribers gaining practical tips and resources to enhance your .NET expertise.