Skip to content
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
47 changes: 8 additions & 39 deletions aspnetcore/release-notes/aspnetcore-10/includes/openApi.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,13 @@ Some of the changes you will see in the generated OpenAPI document include:
and have a `pattern` field limiting the value to digits.
This happens when the <xref:System.Text.Json.JsonSerializerOptions.NumberHandling> property in the <xref:System.Text.Json.JsonSerializerOptions> is set to `AllowReadingFromString`, the default for ASP.NET Core Web apps. To enable C# `int` and `long` to be represented in the OpenAPI document as `type: integer`, set the <xref:System.Text.Json.JsonSerializerOptions.NumberHandling> property to `Strict`.

With this feature, the default OpenAPI version for generated documents is`3.1`. The version can be changed by explicitly setting the [OpenApiVersion](/dotnet/api/microsoft.aspnetcore.openapi.openapioptions.openapiversion) property of the [OpenApiOptions](/dotnet/api/microsoft.aspnetcore.openapi.openapioptions) in the `configureOptions` delegate parameter of [AddOpenApi](/dotnet/api/microsoft.extensions.dependencyinjection.openapiservicecollectionextensions.addopenapi).
With this feature, the default OpenAPI version for generated documents is`3.1`. The version can be changed by explicitly setting the [OpenApiVersion](/dotnet/api/microsoft.aspnetcore.openapi.openapioptions.openapiversion) property of the [OpenApiOptions](/dotnet/api/microsoft.aspnetcore.openapi.openapioptions) in the `configureOptions` delegate parameter of [AddOpenApi](/dotnet/api/microsoft.extensions.dependencyinjection.openapiservicecollectionextensions.addopenapi):

```csharp
builder.Services.AddOpenApi(options =>
{
// Specify the OpenAPI version to use.
options.OpenApiVersion = Microsoft.OpenApi.OpenApiSpecVersion.OpenApi3_0;
});
```
:::code language="csharp" source="~/release-notes/aspnetcore-10/samples/WebAppOpenAPI10/Program.cs" id="snippet_DefaultOpenApiVersion" highlight="3":::

When generating the OpenAPI document at build time, the OpenAPI version can be selected by setting the `--openapi-version` in the `OpenApiGenerateDocumentsOptions` MSBuild item.
When generating the OpenAPI document at build time, the OpenAPI version can be selected by setting the `--openapi-version` in the `OpenApiGenerateDocumentsOptions` MSBuild item:

```xml
<!-- Configure build-time OpenAPI generation to produce an OpenAPI 3.0 document. -->
<OpenApiGenerateDocumentsOptions>--openapi-version OpenApi3_0</OpenApiGenerateDocumentsOptions>
```
:::code language="xml" source="~/release-notes/aspnetcore-10/samples/WebAppOpenAPI10/WebAppOpenAPI10.csproj" id="snippet_ConfigBuildTimeOpenApiDocVersion" highlight="7":::

OpenAPI 3.1 support was primarily added in the following [PR](https://github.com/dotnet/aspnetcore/pull/59480).

Expand All @@ -42,29 +33,9 @@ Breaking changes in this iteration include the following:
* Entities within the OpenAPI document, like operations and parameters, are typed as interfaces. Concrete implementations exist for the inlined and referenced variants of an entity. For example, an `IOpenApiSchema` can either be an inlined `OpenApiSchema` or an `OpenApiSchemaReference` that points to a schema defined elsewhere in the document.
* The `Nullable` property has been removed from the `OpenApiSchema` type. To determine if a type is nullable, evaluate if the `OpenApiSchema.Type` property sets `JsonSchemaType.Null`.

One of the most significant changes is that the `OpenApiAny` class has been dropped in favor of using `JsonNode` directly. Transformers that use `OpenApiAny` need to be updated to use `JsonNode`. The following diff shows the changes in schema transformer from .NET 9 to .NET 10:

```diff
options.AddSchemaTransformer((schema, context, cancellationToken) =>
{
if (context.JsonTypeInfo.Type == typeof(WeatherForecast))
{
- schema.Example = new OpenApiObject
+ schema.Example = new JsonObject
{
- ["date"] = new OpenApiString(DateTime.Now.AddDays(1).ToString("yyyy-MM-dd")),
+ ["date"] = DateTime.Now.AddDays(1).ToString("yyyy-MM-dd"),
- ["temperatureC"] = new OpenApiInteger(0),
+ ["temperatureC"] = 0,
- ["temperatureF"] = new OpenApiInteger(32),
+ ["temperatureF"] = 32,
- ["summary"] = new OpenApiString("Bracing"),
+ ["summary"] = "Bracing",
};
}
return Task.CompletedTask;
});
```
One of the most significant changes is that the `OpenApiAny` class has been dropped in favor of using `JsonNode` directly. Transformers that use `OpenApiAny` need to be updated to use `JsonNode`. The following diff shows the changes in schema transformer from .NET 9 to .NET 10:

:::code language="diff" source="~/release-notes/aspnetcore-10/samples/WebAppOpenAPI10/TransformerJsonNode.cs":::

Note that these changes are necessary even when only configuring the OpenAPI version to 3.0.

Expand All @@ -74,9 +45,7 @@ ASP.NET now supports serving the generated OpenAPI document in YAML format. YAML

To configure an app to serve the generated OpenAPI document in YAML format, specify the endpoint in the MapOpenApi call with a ".yaml" or ".yml" suffix, as shown in the following example:

```csharp
app.MapOpenApi("/openapi/{documentName}.yaml");
```
:::code language="csharp" source="~/release-notes/aspnetcore-10/samples/WebAppOpenAPI10/Program.cs" id="snippet_ConfigOpenApiYAML" highlight="3":::

Support for:

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Microsoft.AspNetCore.Mvc;

namespace WebAppOpenAPI10.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries =
[
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
];

[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
// <snippet_DefaultOpenApiVersion>
builder.Services.AddOpenApi(options =>
{
options.OpenApiVersion = Microsoft.OpenApi.OpenApiSpecVersion.OpenApi3_0;
});
// </snippet_DefaultOpenApiVersion>

var app = builder.Build();

// Configure the HTTP request pipeline.
// <snippet_ConfigOpenApiYAML>
if (app.Environment.IsDevelopment())
{
app.MapOpenApi("/openapi/{documentName}.yaml");
}
// </snippet_ConfigOpenApiYAML>

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
options.AddSchemaTransformer((schema, context, cancellationToken) =>
{
if (context.JsonTypeInfo.Type == typeof(WeatherForecast))
{
- schema.Example = new OpenApiObject
+ schema.Example = new JsonObject
{
- ["date"] = new OpenApiString(DateTime.Now.AddDays(1).ToString("yyyy-MM-dd")),
+ ["date"] = DateTime.Now.AddDays(1).ToString("yyyy-MM-dd"),
- ["temperatureC"] = new OpenApiInteger(0),
+ ["temperatureC"] = 0,
- ["temperatureF"] = new OpenApiInteger(32),
+ ["temperatureF"] = 32,
- ["summary"] = new OpenApiString("Bracing"),
+ ["summary"] = "Bracing",
};
}
return Task.CompletedTask;
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace WebAppOpenAPI10
{
public class WeatherForecast
{
public DateOnly Date { get; set; }

public int TemperatureC { get; set; }

public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

public string? Summary { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<!-- <snippet_ConfigBuildTimeOpenApiDocVersion> -->
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<OpenApiGenerateDocuments>true</OpenApiGenerateDocuments>
<!-- Configure build-time OpenAPI generation to produce an OpenAPI 3.0 document. -->
<OpenApiGenerateDocumentsOptions>--openapi-version OpenApi3_0</OpenApiGenerateDocumentsOptions>
</PropertyGroup>
<!-- </snippet_ConfigBuildTimeOpenApiDocVersion> -->

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0-preview.3.25172.1" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@WebAppOpenAPI10_HostAddress = http://localhost:5077

GET {{WebAppOpenAPI10_HostAddress}}/weatherforecast/
Accept: application/json

###
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}