Skip to content

[Docs] Split readme md #3405

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,656 changes: 54 additions & 1,602 deletions README.md

Large diffs are not rendered by default.

221 changes: 221 additions & 0 deletions docs/configure-and-customize-annotations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
# Configuration & Customization of `Swashbuckle.AspNetCore.Annotations`

## Install and Enable Annotations

1. Install the following Nuget package into your ASP.NET Core application.

```
Package Manager : Install-Package Swashbuckle.AspNetCore.Annotations
CLI : dotnet add package Swashbuckle.AspNetCore.Annotations
```

2. In the `ConfigureServices` method of `Startup.cs`, enable annotations within in the Swagger config block:

```csharp
services.AddSwaggerGen(c =>
{
...

c.EnableAnnotations();
});
```

## Enrich Operation Metadata

Once annotations have been enabled, you can enrich the generated Operation metadata by decorating actions with a `SwaggerOperationAttribute`.

```csharp
[HttpPost]

[SwaggerOperation(
Summary = "Creates a new product",
Description = "Requires admin privileges",
OperationId = "CreateProduct",
Tags = new[] { "Purchase", "Products" }
)]
public IActionResult Create([FromBody]Product product)
```

## Enrich Response Metadata

ASP.NET Core provides the `ProducesResponseTypeAttribute` for listing the different responses that can be returned by an action. These attributes can be combined with XML comments, as described [above](#include-descriptions-from-xml-comments), to include human friendly descriptions with each response in the generated Swagger. If you'd prefer to do all of this with a single attribute, and avoid the use of XML comments, you can use `SwaggerResponseAttribute`s instead:

```csharp
[HttpPost]
[SwaggerResponse(201, "The product was created", typeof(Product))]
[SwaggerResponse(400, "The product data is invalid")]
public IActionResult Create([FromBody]Product product)
```

## Enrich Parameter Metadata

You can annotate "path", "query" or "header" bound parameters or properties (i.e. decorated with `[FromRoute]`, `[FromQuery]` or `[FromHeader]`) with a `SwaggerParameterAttribute` to enrich the corresponding `Parameter` metadata that's generated by Swashbuckle:

```csharp
[HttpGet]
public IActionResult GetProducts(
[FromQuery, SwaggerParameter("Search keywords", Required = true)]string keywords)
```

## Enrich RequestBody Metadata

You can annotate "body" bound parameters or properties (i.e. decorated with `[FromBody]`) with a `SwaggerRequestBodyAttribute` to enrich the corresponding `RequestBody` metadata that's generated by Swashbuckle:

```csharp
[HttpPost]
public IActionResult CreateProduct(
[FromBody, SwaggerRequestBody("The product payload", Required = true)]Product product)
```

## Enrich Schema Metadata

You can annotate classes or properties with a `SwaggerSchemaAttribute` to enrich the corresponding `Schema` metadata that's generated by Swashbuckle:

```csharp
[SwaggerSchema(Required = new[] { "Description" })]
public class Product
{
[SwaggerSchema("The product identifier", ReadOnly = true)]
public int Id { get; set; }

[SwaggerSchema("The product description")]
public string Description { get; set; }

[SwaggerSchema("The date it was created", Format = "date")]
public DateTime DateCreated { get; set; }
}
```

_NOTE: In Swagger / OpenAPI, serialized objects AND contained properties are represented as `Schema` instances, hence why this annotation can be applied to both classes and properties. Also worth noting, "required" properties are specified as an array of property names on the top-level schema as opposed to a flag on each individual property._

## Apply Schema Filters to Specific Types

The `SwaggerGen` package provides several extension points, including Schema Filters ([described here](#extend-generator-with-operation-schema--document-filter)) for customizing ALL generated Schemas. However, there may be cases where it's preferable to apply a filter to a specific Schema. For example, if you'd like to include an example for a specific type in your API. This can be done by decorating the type with a `SwaggerSchemaFilterAttribute`:

```csharp
// Product.cs
[SwaggerSchemaFilter(typeof(ProductSchemaFilter))]
public class Product
{
...
}

// ProductSchemaFilter.cs
public class ProductSchemaFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
schema.Example = new OpenApiObject
{
[ "Id" ] = new OpenApiInteger(1),
[ "Description" ] = new OpenApiString("An awesome product")
};
}
}
```

## Add Tag Metadata

By default, the Swagger generator will tag all operations with the controller name. This tag is then used to drive the operation groupings in the swagger-ui. If you'd like to provide a description for each of these groups, you can do so by adding metadata for each controller name tag via the `SwaggerTagAttribute`:

```csharp
[SwaggerTag("Create, read, update and delete Products")]
public class ProductsController
{
...
}
```

_NOTE: This will add the above description specifically to the tag named "Products". Therefore, you should avoid using this attribute if you're tagging Operations with something other than controller name - e.g. if you're customizing the tagging behavior with `TagActionsBy`._

## List Known Subtypes for Inheritance and Polymorphism

If you want to use Swashbuckle's [inheritance and/or polymorphism behavior](#inheritance-and-polymorphism), you can use annotations to _explicitly_ indicate the "known" subtypes for a given base type. This will override the default selector function, which selects _all_ subtypes in the same assembly as the base type, and therefore needs to be explicitly enabled when you enable Annotations:

```csharp
// Startup.cs
services.AddSwaggerGen(c =>
{
c.EnableAnnotations(enableAnnotationsForInheritance: true, enableAnnotationsForPolymorphism: true);
});

// Shape.cs

// .NET 7 or later
[JsonDerivedType(typeof(Rectangle))]
[JsonDerivedType(typeof(Circle))]
public abstract class Shape
{
}

// .NET 6 or earlier
[SwaggerSubType(typeof(Rectangle))]
[SwaggerSubType(typeof(Circle))]
public abstract class Shape
{
}
```

## Enrich Polymorphic Base Classes with Discriminator Metadata

If you're using annotations to _explicitly_ indicate the "known" subtypes for a polymorphic base type, you can combine the `JsonPolymorphicAttribute` with the `JsonDerivedTypeAttribute` to provide additional metadata about the "discriminator" property, which will then be incorporated into the generated schema definition:


```csharp
// Startup.cs
services.AddSwaggerGen(c =>
{
c.EnableAnnotations(enableAnnotationsForInheritance: true, enableAnnotationsForPolymorphism: true);
});

// Shape.cs

// .NET 7 or later
[JsonPolymorphic(TypeDiscriminatorPropertyName = "shapeType")]
[JsonDerivedType(typeof(Rectangle), "rectangle")]
[JsonDerivedType(typeof(Circle), "circle")]
public abstract class Shape
{
// Avoid using a JsonPolymorphicAttribute.TypeDiscriminatorPropertyName
// that conflicts with a property in your type hierarchy.
// Related issue: https://github.com/dotnet/runtime/issues/72170
}

// .NET 6 or earlier
[SwaggerDiscriminator("shapeType")]
[SwaggerSubType(typeof(Rectangle), DiscriminatorValue = "rectangle")]
[SwaggerSubType(typeof(Circle), DiscriminatorValue = "circle")]
public abstract class Shape
{
public ShapeType ShapeType { get; set; }
}

[JsonConverter(typeof(JsonStringEnumConverter))]
public enum ShapeType
{
Circle,
Rectangle
}
```

This indicates that the corresponding payload will have a "shapeType" property to discriminate between subtypes, and that property will have a value of "rectangle" if the payload represents a `Rectangle` type and a value of "circle" if it represents a `Circle` type. This detail will be described in the generated schema definition as follows:

```
schema: {
oneOf: [
{
$ref: "#/components/schemas/Rectangle"
},
{
$ref: "#/components/schemas/Circle"
},
],
discriminator: {
propertyName: shapeType,
mapping: {
rectangle: "#/components/schemas/Rectangle",
circle: "#/components/schemas/Circle",
}
}
}
```
86 changes: 86 additions & 0 deletions docs/configure-and-customize-cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Configuration & Customization of `Swashbuckle.AspNetCore.Cli`

## Retrieve Swagger Directly from a Startup Assembly

Once your application has been setup with Swashbuckle (see [Getting Started](#getting-started)), you can use the Swashbuckle CLI tool to retrieve Swagger / OpenAPI JSON directly from your application's startup assembly, and write it to file. This can be useful if you want to incorporate Swagger generation into a CI/CD process, or if you want to serve it from static file at run-time.

It's packaged as a [.NET Tool](https://learn.microsoft.com/dotnet/core/tools/global-tools) that can be installed and used via the dotnet SDK.

> :warning: The tool needs to load your Startup DLL and its dependencies at runtime. Therefore, you should use a version of the `dotnet` SDK that is compatible with your application. For example, if your app targets `net8.0`, then you should use version 8.0.xxx of the SDK to run the CLI tool. If it targets `net9.0`, then you should use version 9.0.xxx of the SDK and so on.

### Using the tool with the .NET SDK

1. Install as a [global tool](https://learn.microsoft.com/dotnet/core/tools/global-tools#install-a-global-tool)

```
dotnet tool install -g Swashbuckle.AspNetCore.Cli
```

2. Verify that the tool was installed correctly

```
swagger tofile --help
```

3. Generate a Swagger/ OpenAPI document from your application's startup assembly

```
swagger tofile --output [output] [startupassembly] [swaggerdoc]
```

Where ...
* [output] is the relative path where the Swagger JSON will be output to
* [startupassembly] is the relative path to your application's startup assembly
* [swaggerdoc] is the name of the swagger document you want to retrieve, as configured in your startup class

### Using the tool with the .NET 6.0 SDK or later

1. In your project root, create a tool manifest file:

```
dotnet new tool-manifest
```

2. Install as a [local tool](https://learn.microsoft.com/dotnet/core/tools/global-tools#install-a-local-tool)

```
dotnet tool install Swashbuckle.AspNetCore.Cli
```

3. Verify that the tool was installed correctly

```
dotnet swagger tofile --help
```

4. Generate a Swagger / OpenAPI document from your application's startup assembly

```
dotnet swagger tofile --output [output] [startupassembly] [swaggerdoc]
```

Where ...
* [output] is the relative path where the Swagger JSON will be output to
* [startupassembly] is the relative path to your application's startup assembly
* [swaggerdoc] is the name of the swagger document you want to retrieve, as configured in your startup class

## Use the CLI Tool with a Custom Host Configuration

Out-of-the-box, the tool will execute in the context of a "default" web host. However, in some cases you may want to bring your own host environment, for example if you've configured a custom DI container such as Autofac. For this scenario, the Swashbuckle CLI tool exposes a convention-based hook for your application.

That is, if your application contains a class that meets either of the following naming conventions, then that class will be used to provide a host for the CLI tool to run in.

- `public class SwaggerHostFactory`, containing a public static method called `CreateHost` with return type `IHost`
- `public class SwaggerWebHostFactory`, containing a public static method called `CreateWebHost` with return type `IWebHost`

For example, the following class could be used to leverage the same host configuration as your application:

```csharp
public class SwaggerHostFactory
{
public static IHost CreateHost()
{
return Program.CreateHostBuilder(new string[0]).Build();
}
}
```
87 changes: 87 additions & 0 deletions docs/configure-and-customize-redoc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Configuration & Customization of `Swashbuckle.AspNetCore.ReDoc`

## Change Relative Path to the UI

By default, the Redoc UI will be exposed at "/api-docs". If necessary, you can alter this when enabling the Redoc middleware:

```csharp
app.UseReDoc(c =>
{
c.RoutePrefix = "docs"
...
}
```

## Change Document Title

By default, the Redoc UI will have a generic document title. You can alter this when enabling the Redoc middleware:

```csharp
app.UseReDoc(c =>
{
c.DocumentTitle = "My API Docs";
...
}
```

## Apply Redoc Parameters

Redoc ships with its own set of configuration parameters, all described here https://github.com/Rebilly/redoc/blob/main/README.md#redoc-options-object. In Swashbuckle, most of these are surfaced through the Redoc middleware options:

```csharp
app.UseReDoc(c =>
{
c.SpecUrl("/v1/swagger.json");
c.EnableUntrustedSpec();
c.ScrollYOffset(10);
c.HideHostname();
c.HideDownloadButton();
c.ExpandResponses("200,201");
c.RequiredPropsFirst();
c.NoAutoAuth();
c.PathInMiddlePanel();
c.HideLoading();
c.NativeScrollbars();
c.DisableSearch();
c.OnlyRequiredInSamples();
c.SortPropsAlphabetically();
});
```

_Using `c.SpecUrl("/v1/swagger.json")` multiple times within the same `UseReDoc(...)` will not add multiple urls._

## Inject Custom CSS

To tweak the look and feel, you can inject additional CSS stylesheets by adding them to your `wwwroot` folder and specifying the relative paths in the middleware options:

```csharp
app.UseReDoc(c =>
{
...
c.InjectStylesheet("/redoc/custom.css");
}
```

It is also possible to modify the theme by using the `AdditionalItems` property, see https://github.com/Rebilly/redoc/blob/main/README.md#redoc-options-object for more information.

```csharp
app.UseReDoc(c =>
{
...
c.ConfigObject.AdditionalItems = ...
}
```

## Customize index.html

To customize the UI beyond the basic options listed above, you can provide your own version of the Redoc index.html page:

```csharp
app.UseReDoc(c =>
{
c.IndexStream = () => GetType().Assembly
.GetManifestResourceStream("CustomIndex.ReDoc.index.html"); // requires file to be added as an embedded resource
});
```

_To get started, you should base your custom index.html on the [default version](src/Swashbuckle.AspNetCore.ReDoc/index.html)_
Loading