Skip to content

Commit bc1b3b2

Browse files
authored
Update to Microsoft.OpenApi v2.0.0-preview.17 (#61541)
1 parent b5739b5 commit bc1b3b2

File tree

42 files changed

+723
-489
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+723
-489
lines changed

eng/Dependencies.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ and are generated based on the last package release.
7070
<LatestPackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing" />
7171
<LatestPackageReference Include="Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing" />
7272
<LatestPackageReference Include="Microsoft.OpenApi" />
73-
<LatestPackageReference Include="Microsoft.OpenApi.Readers" />
73+
<LatestPackageReference Include="Microsoft.OpenApi.YamlReader" />
7474
<LatestPackageReference Include="System.Buffers" />
7575
<LatestPackageReference Include="System.CodeDom" />
7676
<LatestPackageReference Include="System.CommandLine.Experimental" />

eng/Versions.props

+2-2
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,8 @@
340340
<XunitExtensibilityExecutionVersion>$(XunitVersion)</XunitExtensibilityExecutionVersion>
341341
<XUnitRunnerVisualStudioVersion>2.8.2</XUnitRunnerVisualStudioVersion>
342342
<MicrosoftDataSqlClientVersion>5.2.2</MicrosoftDataSqlClientVersion>
343-
<MicrosoftOpenApiVersion>2.0.0-preview.11</MicrosoftOpenApiVersion>
344-
<MicrosoftOpenApiReadersVersion>2.0.0-preview.11</MicrosoftOpenApiReadersVersion>
343+
<MicrosoftOpenApiVersion>2.0.0-preview.17</MicrosoftOpenApiVersion>
344+
<MicrosoftOpenApiYamlReaderVersion>2.0.0-preview.17</MicrosoftOpenApiYamlReaderVersion>
345345
<!-- dotnet tool versions (see also auto-updated DotnetEfVersion property). -->
346346
<DotnetDumpVersion>6.0.322601</DotnetDumpVersion>
347347
<DotnetServeVersion>1.10.93</DotnetServeVersion>

src/OpenApi/OpenApi.slnf

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
"src\\Servers\\Connections.Abstractions\\src\\Microsoft.AspNetCore.Connections.Abstractions.csproj",
1818
"src\\OpenApi\\test\\Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests\\Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests.csproj",
1919
"src\\OpenApi\\test\\Microsoft.AspNetCore.OpenApi.Tests\\Microsoft.AspNetCore.OpenApi.Tests.csproj",
20-
"src\\OpenApi\\sample\\Sample.csproj",
2120
"src\\OpenApi\\perf\\Microbenchmarks\\Microsoft.AspNetCore.OpenApi.Microbenchmarks.csproj"
2221
]
2322
}

src/OpenApi/gen/XmlCommentGenerator.Emitter.cs

+31-4
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ namespace Microsoft.AspNetCore.OpenApi.Generated
5959
using Microsoft.AspNetCore.Mvc.Controllers;
6060
using Microsoft.Extensions.DependencyInjection;
6161
using Microsoft.OpenApi.Models;
62+
using Microsoft.OpenApi.Models.Interfaces;
6263
using Microsoft.OpenApi.Models.References;
6364
using Microsoft.OpenApi.Any;
6465
@@ -341,9 +342,7 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
341342
var operationParameter = operation.Parameters?.SingleOrDefault(parameter => parameter.Name == parameterComment.Name);
342343
if (operationParameter is not null)
343344
{
344-
var targetOperationParameter = operationParameter is OpenApiParameterReference reference
345-
? reference.Target
346-
: (OpenApiParameter)operationParameter;
345+
var targetOperationParameter = UnwrapOpenApiParameter(operationParameter);
347346
targetOperationParameter.Description = parameterComment.Description;
348347
if (parameterComment.Example is { } jsonString)
349348
{
@@ -359,7 +358,12 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
359358
requestBody.Description = parameterComment.Description;
360359
if (parameterComment.Example is { } jsonString)
361360
{
362-
foreach (var mediaType in requestBody.Content.Values)
361+
var content = requestBody?.Content?.Values;
362+
if (content is null)
363+
{
364+
continue;
365+
}
366+
foreach (var mediaType in content)
363367
{
364368
mediaType.Example = jsonString.Parse();
365369
}
@@ -383,6 +387,29 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform
383387
384388
return Task.CompletedTask;
385389
}
390+
391+
private static OpenApiParameter UnwrapOpenApiParameter(IOpenApiParameter sourceParameter)
392+
{
393+
if (sourceParameter is OpenApiParameterReference parameterReference)
394+
{
395+
if (parameterReference.Target is OpenApiParameter target)
396+
{
397+
return target;
398+
}
399+
else
400+
{
401+
throw new InvalidOperationException($"The input schema must be an {nameof(OpenApiParameter)} or {nameof(OpenApiParameterReference)}.");
402+
}
403+
}
404+
else if (sourceParameter is OpenApiParameter directParameter)
405+
{
406+
return directParameter;
407+
}
408+
else
409+
{
410+
throw new InvalidOperationException($"The input schema must be an {nameof(OpenApiParameter)} or {nameof(OpenApiParameterReference)}.");
411+
}
412+
}
386413
}
387414
388415
{{GeneratedCodeAttribute}}

src/OpenApi/perf/Microbenchmarks/TransformersBenchmark.cs

+2
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ public void SchemaTransformer_Setup()
102102
{
103103
_options.AddSchemaTransformer((schema, context, token) =>
104104
{
105+
schema.Extensions ??= [];
105106
if (context.JsonTypeInfo.Type == typeof(Todo) && context.ParameterDescription != null)
106107
{
107108
schema.Extensions["x-my-extension"] = new OpenApiAny(context.ParameterDescription.Name);
@@ -175,6 +176,7 @@ private class SchemaTransformer : IOpenApiSchemaTransformer
175176
{
176177
public Task TransformAsync(OpenApiSchema schema, OpenApiSchemaTransformerContext context, CancellationToken cancellationToken)
177178
{
179+
schema.Extensions ??= [];
178180
if (context.JsonTypeInfo.Type == typeof(Todo) && context.ParameterDescription != null)
179181
{
180182
schema.Extensions["x-my-extension"] = new OpenApiAny(context.ParameterDescription.Name);

src/OpenApi/src/Extensions/ApiDescriptionExtensions.cs

+13-13
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,30 @@
44
using System.Diagnostics;
55
using System.Diagnostics.CodeAnalysis;
66
using System.Linq;
7+
using System.Net.Http;
78
using System.Text;
89
using Microsoft.AspNetCore.Mvc.ApiExplorer;
910
using Microsoft.AspNetCore.Mvc.ModelBinding;
1011
using Microsoft.AspNetCore.Routing.Patterns;
11-
using Microsoft.OpenApi.Models;
1212

1313
internal static class ApiDescriptionExtensions
1414
{
1515
/// <summary>
16-
/// Maps the HTTP method of the ApiDescription to the OpenAPI <see cref="OperationType"/> .
16+
/// Maps the HTTP method of the ApiDescription to the HttpMethod.
1717
/// </summary>
18-
/// <param name="apiDescription">The ApiDescription to resolve an operation type from.</param>
19-
/// <returns>The <see cref="OperationType"/> associated with the given <paramref name="apiDescription"/>.</returns>
20-
public static OperationType GetOperationType(this ApiDescription apiDescription) =>
18+
/// <param name="apiDescription">The ApiDescription to resolve an HttpMethod from.</param>
19+
/// <returns>The <see cref="HttpMethod"/> associated with the given <paramref name="apiDescription"/>.</returns>
20+
public static HttpMethod GetHttpMethod(this ApiDescription apiDescription) =>
2121
apiDescription.HttpMethod?.ToUpperInvariant() switch
2222
{
23-
"GET" => OperationType.Get,
24-
"POST" => OperationType.Post,
25-
"PUT" => OperationType.Put,
26-
"DELETE" => OperationType.Delete,
27-
"PATCH" => OperationType.Patch,
28-
"HEAD" => OperationType.Head,
29-
"OPTIONS" => OperationType.Options,
30-
"TRACE" => OperationType.Trace,
23+
"GET" => HttpMethod.Get,
24+
"POST" => HttpMethod.Post,
25+
"PUT" => HttpMethod.Put,
26+
"DELETE" => HttpMethod.Delete,
27+
"PATCH" => HttpMethod.Patch,
28+
"HEAD" => HttpMethod.Head,
29+
"OPTIONS" => HttpMethod.Options,
30+
"TRACE" => HttpMethod.Trace,
3131
_ => throw new InvalidOperationException($"Unsupported HTTP method: {apiDescription.HttpMethod}"),
3232
};
3333

src/OpenApi/src/Extensions/JsonNodeSchemaExtensions.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ internal static void MapPolymorphismOptionsToDiscriminator(this JsonNode schema,
386386
// that we hardcode here. We could use `OpenApiReference` to construct the reference and
387387
// serialize it but we use a hardcoded string here to avoid allocating a new object and
388388
// working around Microsoft.OpenApi's serialization libraries.
389-
mappings[$"{discriminator}"] = $"#/components/schemas/{createSchemaReferenceId(context.TypeInfo)}{createSchemaReferenceId(jsonDerivedType)}";
389+
mappings[$"{discriminator}"] = $"{createSchemaReferenceId(context.TypeInfo)}{createSchemaReferenceId(jsonDerivedType)}";
390390
}
391391
}
392392
schema[OpenApiSchemaKeywords.DiscriminatorKeyword] = polymorphismOptions.TypeDiscriminatorPropertyName;

src/OpenApi/src/Schemas/OpenApiJsonSchema.Helpers.cs

+15-8
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Diagnostics;
5+
using System.Globalization;
56
using System.Linq;
67
using System.Text.Json;
78
using System.Text.Json.Nodes;
89
using System.Text.Json.Serialization;
910
using Microsoft.AspNetCore.OpenApi;
1011
using Microsoft.OpenApi.Models;
1112
using Microsoft.OpenApi.Models.Interfaces;
13+
using Microsoft.OpenApi.Models.References;
1214
using OpenApiConstants = Microsoft.AspNetCore.OpenApi.OpenApiConstants;
1315

1416
internal sealed partial class OpenApiJsonSchema
@@ -256,12 +258,12 @@ public static void ReadProperty(ref Utf8JsonReader reader, string propertyName,
256258
case OpenApiSchemaKeywords.MinimumKeyword:
257259
reader.Read();
258260
var minimum = reader.GetDecimal();
259-
schema.Minimum = minimum;
261+
schema.Minimum = minimum.ToString(CultureInfo.InvariantCulture);
260262
break;
261263
case OpenApiSchemaKeywords.MaximumKeyword:
262264
reader.Read();
263265
var maximum = reader.GetDecimal();
264-
schema.Maximum = maximum;
266+
schema.Maximum = maximum.ToString(CultureInfo.InvariantCulture);
265267
break;
266268
case OpenApiSchemaKeywords.PatternKeyword:
267269
reader.Read();
@@ -302,25 +304,30 @@ public static void ReadProperty(ref Utf8JsonReader reader, string propertyName,
302304
var mappings = ReadDictionary<string>(ref reader);
303305
if (mappings is not null)
304306
{
305-
schema.Discriminator.Mapping = mappings;
307+
schema.Discriminator ??= new OpenApiDiscriminator();
308+
foreach (var kvp in mappings)
309+
{
310+
schema.Discriminator.Mapping ??= [];
311+
schema.Discriminator.Mapping[kvp.Key] = new OpenApiSchemaReference(kvp.Value);
312+
}
306313
}
307314
break;
308315
case OpenApiConstants.SchemaId:
309316
reader.Read();
310-
schema.Annotations ??= new Dictionary<string, object>();
311-
schema.Annotations.Add(OpenApiConstants.SchemaId, reader.GetString());
317+
schema.Metadata ??= [];
318+
schema.Metadata.Add(OpenApiConstants.SchemaId, reader.GetString() ?? string.Empty);
312319
break;
313320
// OpenAPI does not support the `const` keyword in its schema implementation, so
314321
// we map it to its closest approximation, an enum with a single value, here.
315322
case OpenApiSchemaKeywords.ConstKeyword:
316323
reader.Read();
317-
schema.Enum = [ReadJsonNode(ref reader, out var constType)];
324+
schema.Enum = ReadJsonNode(ref reader, out var constType) is { } jsonNode ? [jsonNode] : [];
318325
schema.Type = constType;
319326
break;
320327
case OpenApiSchemaKeywords.RefKeyword:
321328
reader.Read();
322-
schema.Annotations ??= new Dictionary<string, object>();
323-
schema.Annotations[OpenApiConstants.RefId] = reader.GetString();
329+
schema.Metadata ??= [];
330+
schema.Metadata[OpenApiConstants.RefId] = reader.GetString() ?? string.Empty;
324331
break;
325332
default:
326333
reader.Skip();

src/OpenApi/src/Services/OpenApiConstants.cs

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
using Microsoft.OpenApi.Models;
4+
using System.Net.Http;
55

66
namespace Microsoft.AspNetCore.OpenApi;
77

@@ -14,19 +14,19 @@ internal static class OpenApiConstants
1414
internal const string SchemaId = "x-schema-id";
1515
internal const string RefId = "x-ref-id";
1616
internal const string DefaultOpenApiResponseKey = "default";
17-
// Since there's a finite set of operation types that can be included in a given
18-
// OpenApiPaths, we can pre-allocate an array of these types and use a direct
17+
// Since there's a finite set of HTTP methods that can be included in a given
18+
// OpenApiPaths, we can pre-allocate an array of these methods and use a direct
1919
// lookup on the OpenApiPaths dictionary to avoid allocating an enumerator
2020
// over the KeyValuePairs in OpenApiPaths.
21-
internal static readonly OperationType[] OperationTypes = [
22-
OperationType.Get,
23-
OperationType.Post,
24-
OperationType.Put,
25-
OperationType.Delete,
26-
OperationType.Options,
27-
OperationType.Head,
28-
OperationType.Patch,
29-
OperationType.Trace
21+
internal static readonly HttpMethod[] HttpMethods = [
22+
HttpMethod.Get,
23+
HttpMethod.Post,
24+
HttpMethod.Put,
25+
HttpMethod.Delete,
26+
HttpMethod.Options,
27+
HttpMethod.Head,
28+
HttpMethod.Patch,
29+
HttpMethod.Trace
3030
];
3131
// Represents primitive types that should never be represented as
3232
// a schema reference and always inlined.

0 commit comments

Comments
 (0)