Skip to content

Commit fdd66a5

Browse files
Update to Microsoft.OpenApi 2.0.0 preview 17
Update Microsoft.OpenApi to version 2.0.0-preview.17 using the latest daily build of ASP.NET Core 10 preview 4.
1 parent 21acf10 commit fdd66a5

File tree

45 files changed

+283
-217
lines changed

Some content is hidden

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

45 files changed

+283
-217
lines changed

Directory.Packages.props

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="6.0.32" />
2424
<PackageVersion Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="3.3.4" />
2525
<PackageVersion Include="Microsoft.Extensions.FileProviders.Embedded" Version="2.1.1" />
26-
<PackageVersion Include="Microsoft.OpenApi" Version="2.0.0-preview.11" />
27-
<PackageVersion Include="Microsoft.OpenApi.Readers" Version="2.0.0-preview.11" />
26+
<PackageVersion Include="Microsoft.OpenApi" Version="2.0.0-preview.17" />
27+
<PackageVersion Include="Microsoft.OpenApi.YamlReader" Version="2.0.0-preview.17" />
2828
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
2929
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
3030
<PackageVersion Include="NSubstitute" Version="5.3.0" />
@@ -38,6 +38,6 @@
3838
<PackageVersion Include="xunit.v3.extensibility.core" Version="2.0.1" />
3939
</ItemGroup>
4040
<ItemGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net10.0'))">
41-
<PackageVersion Update="Microsoft.AspNetCore.OpenApi" Version="10.0.0-preview.3.25172.1" />
41+
<PackageVersion Update="Microsoft.AspNetCore.OpenApi" Version="10.0.0-preview.4.25227.102" />
4242
</ItemGroup>
4343
</Project>

NuGet.config

+6
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@
22
<configuration>
33
<packageSources>
44
<clear />
5+
<!-- TODO Remove before merging to dotnet-vnext -->
6+
<add key="dotnet10" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10/nuget/v3/index.json" />
57
<add key="NuGet" value="https://api.nuget.org/v3/index.json" />
68
</packageSources>
79
<packageSourceMapping>
10+
<!-- TODO Remove before merging to dotnet-vnext -->
11+
<packageSource key="dotnet10">
12+
<package pattern="*" />
13+
</packageSource>
814
<packageSource key="NuGet">
915
<package pattern="*" />
1016
</packageSource>

global.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"sdk": {
3-
"version": "10.0.100-preview.3.25201.16",
3+
"version": "10.0.100-preview.4.25227.102",
44
"allowPrerelease": false,
55
"rollForward": "latestMajor",
66
"paths": [ ".dotnet", "$host$" ]

src/Swashbuckle.AspNetCore.Annotations/AnnotationsDocumentFilter.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public class AnnotationsDocumentFilter : IDocumentFilter
88
{
99
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
1010
{
11-
swaggerDoc.Tags ??= new HashSet<OpenApiTag>();
11+
swaggerDoc.Tags ??= [];
1212

1313
// Collect (unique) controller names and custom attributes in a dictionary
1414
var controllerNamesAndAttributes = context.ApiDescriptions

src/Swashbuckle.AspNetCore.Annotations/AnnotationsOperationFilter.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ private static void ApplySwaggerOperationAttribute(
7272

7373
if (swaggerOperationAttribute.Tags is { } tags)
7474
{
75-
operation.Tags = new HashSet<OpenApiTagReference>(tags.Select(tagName => new OpenApiTagReference(tagName)));
75+
operation.Tags = [.. tags.Select(tagName => new OpenApiTagReference(tagName))];
7676
}
7777
}
7878

@@ -120,6 +120,7 @@ private static void ApplySwaggerResponseAttributes(
120120
swaggerResponseAttribute.ContentTypes is { } contentTypes)
121121
{
122122
concrete.Content?.Clear();
123+
concrete.Content ??= [];
123124

124125
foreach (var contentType in contentTypes)
125126
{

src/Swashbuckle.AspNetCore.Annotations/AnnotationsSchemaFilter.cs

+8-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,14 @@ private static void ApplySchemaAttribute(IOpenApiSchema schema, SwaggerSchemaAtt
114114

115115
if (schemaAttribute.Required is { } required)
116116
{
117-
concrete.Required = new SortedSet<string>(required);
117+
if (required.Length < 2)
118+
{
119+
concrete.Required = [.. required];
120+
}
121+
else
122+
{
123+
concrete.Required = [.. new SortedSet<string>(required)];
124+
}
118125
}
119126

120127
if (schemaAttribute.Title is { } title)

src/Swashbuckle.AspNetCore.ApiTesting.Xunit/ApiTestFixture.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class ApiTestFixture<TEntryPoint>(
1515
private readonly WebApplicationFactory<TEntryPoint> _webAppFactory = webAppFactory;
1616
private readonly string _documentName = documentName;
1717

18-
public void Describe(string pathTemplate, OperationType operationType, OpenApiOperation operationSpec)
18+
public void Describe(string pathTemplate, HttpMethod operationType, OpenApiOperation operationSpec)
1919
{
2020
_apiTestRunner.ConfigureOperation(_documentName, pathTemplate, operationType, operationSpec);
2121
}

src/Swashbuckle.AspNetCore.ApiTesting/ApiTestRunnerBase.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public void Configure(Action<ApiTestRunnerOptions> setupAction)
2424
public void ConfigureOperation(
2525
string documentName,
2626
string pathTemplate,
27-
OperationType operationType,
27+
HttpMethod operationType,
2828
OpenApiOperation operation)
2929
{
3030
var openApiDocument = _options.GetOpenApiDocument(documentName);

src/Swashbuckle.AspNetCore.ApiTesting/JsonValidation/JsonNumberValidator.cs

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Globalization;
12
using Microsoft.OpenApi.Models;
23
using Microsoft.OpenApi.Models.Interfaces;
34
using Newtonsoft.Json.Linq;
@@ -29,22 +30,30 @@ public bool Validate(
2930
errors.Add($"Path: {instance.Path}. Number is not evenly divisible by multipleOf");
3031
}
3132

32-
if (schema.ExclusiveMaximum is { } exclusiveMaximum && (numberValue >= exclusiveMaximum))
33+
if (schema.ExclusiveMaximum is { } exclusiveMaximum &&
34+
decimal.TryParse(exclusiveMaximum, out var exclusiveMaximumValue) &&
35+
numberValue >= exclusiveMaximumValue)
3336
{
3437
errors.Add($"Path: {instance.Path}. Number is greater than, or equal to, maximum");
3538
}
3639

37-
if (schema.Maximum is { } maximum && numberValue > maximum)
40+
if (schema.Maximum is { } maximum &&
41+
decimal.TryParse(maximum, out var maximumValue) &&
42+
numberValue > maximumValue)
3843
{
3944
errors.Add($"Path: {instance.Path}. Number is greater than maximum");
4045
}
4146

42-
if (schema.ExclusiveMinimum is { } exclusiveMinimum && (numberValue <= exclusiveMinimum))
47+
if (schema.ExclusiveMinimum is { } exclusiveMinimum &&
48+
decimal.TryParse(exclusiveMinimum, out var exclusiveMinimumValue) &&
49+
numberValue <= exclusiveMinimumValue)
4350
{
4451
errors.Add($"Path: {instance.Path}. Number is less than, or equal to, minimum");
4552
}
4653

47-
if (schema.Minimum is { } minimum && numberValue < minimum)
54+
if (schema.Minimum is { } minimum &&
55+
decimal.TryParse(minimum, out var minimumValue) &&
56+
numberValue < minimumValue)
4857
{
4958
errors.Add($"Path: {instance.Path}. Number is less than minimum");
5059
}

src/Swashbuckle.AspNetCore.ApiTesting/OpenApiDocumentExtensions.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ internal static bool TryFindOperationById(
99
this OpenApiDocument openApiDocument,
1010
string operationId,
1111
out string pathTemplate,
12-
out OperationType operationType)
12+
out HttpMethod operationType)
1313
{
1414
if (openApiDocument.Paths is { Count: > 0 } paths)
1515
{
@@ -40,7 +40,7 @@ internal static bool TryFindOperationById(
4040
internal static OpenApiOperation GetOperationByPathAndType(
4141
this OpenApiDocument openApiDocument,
4242
string pathTemplate,
43-
OperationType operationType,
43+
HttpMethod operationType,
4444
out IOpenApiPathItem pathSpec)
4545
{
4646
if (openApiDocument.Paths.TryGetValue(pathTemplate, out pathSpec))

src/Swashbuckle.AspNetCore.ApiTesting/RequestValidator.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public void Validate(
1616
HttpRequestMessage request,
1717
OpenApiDocument openApiDocument,
1818
string pathTemplate,
19-
OperationType operationType)
19+
HttpMethod operationType)
2020
{
2121
var operationSpec = openApiDocument.GetOperationByPathAndType(pathTemplate, operationType, out var pathSpec);
2222
IOpenApiParameter[] parameterSpecs = [];

src/Swashbuckle.AspNetCore.ApiTesting/ResponseValidator.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public void Validate(
1212
HttpResponseMessage response,
1313
OpenApiDocument openApiDocument,
1414
string pathTemplate,
15-
OperationType operationType,
15+
HttpMethod operationType,
1616
string expectedStatusCode)
1717
{
1818
var operationSpec = openApiDocument.GetOperationByPathAndType(pathTemplate, operationType, out _);
@@ -68,7 +68,7 @@ private static void ValidateHeaders(
6868
}
6969

7070
private void ValidateContent(
71-
IDictionary<string, OpenApiMediaType> contentSpecs,
71+
Dictionary<string, OpenApiMediaType> contentSpecs,
7272
OpenApiDocument openApiDocument,
7373
HttpContent content)
7474
{

src/Swashbuckle.AspNetCore.ApiTesting/Swashbuckle.AspNetCore.ApiTesting.csproj

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
<ItemGroup>
1313
<PackageReference Include="Microsoft.OpenApi" />
14-
<PackageReference Include="Microsoft.OpenApi.Readers" />
1514
<PackageReference Include="Newtonsoft.Json" />
1615
</ItemGroup>
1716

@@ -28,7 +27,7 @@
2827
</ItemGroup>
2928

3029
<ItemGroup Condition=" '$(TargetFramework)' == 'net10.0' ">
31-
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" VersionOverride="10.0.0-preview.3.25172.1" />
30+
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" VersionOverride="10.0.0-preview.4.25227.102" />
3231
</ItemGroup>
3332

3433
<ItemGroup>

src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/OpenApiSchemaExtensions.cs

+6-6
Original file line numberDiff line numberDiff line change
@@ -253,11 +253,11 @@ private static void ApplyBase64Attribute(OpenApiSchema schema)
253253
private static void ApplyRangeAttribute(OpenApiSchema schema, RangeAttribute rangeAttribute)
254254
{
255255
schema.Maximum = decimal.TryParse(rangeAttribute.Maximum.ToString(), out decimal maximum)
256-
? maximum
256+
? maximum.ToString(CultureInfo.InvariantCulture)
257257
: schema.Maximum;
258258

259259
schema.Minimum = decimal.TryParse(rangeAttribute.Minimum.ToString(), out decimal minimum)
260-
? minimum
260+
? minimum.ToString()
261261
: schema.Minimum;
262262

263263
#if NET
@@ -275,15 +275,15 @@ private static void ApplyRangeAttribute(OpenApiSchema schema, RangeAttribute ran
275275

276276
private static void ApplyRangeRouteConstraint(OpenApiSchema schema, RangeRouteConstraint rangeRouteConstraint)
277277
{
278-
schema.Maximum = rangeRouteConstraint.Max;
279-
schema.Minimum = rangeRouteConstraint.Min;
278+
schema.Maximum = rangeRouteConstraint.Max.ToString(CultureInfo.InvariantCulture);
279+
schema.Minimum = rangeRouteConstraint.Min.ToString(CultureInfo.InvariantCulture);
280280
}
281281

282282
private static void ApplyMinRouteConstraint(OpenApiSchema schema, MinRouteConstraint minRouteConstraint)
283-
=> schema.Minimum = minRouteConstraint.Min;
283+
=> schema.Minimum = minRouteConstraint.Min.ToString(CultureInfo.InvariantCulture);
284284

285285
private static void ApplyMaxRouteConstraint(OpenApiSchema schema, MaxRouteConstraint maxRouteConstraint)
286-
=> schema.Maximum = maxRouteConstraint.Max;
286+
=> schema.Maximum = maxRouteConstraint.Max.ToString(CultureInfo.InvariantCulture);
287287

288288
private static void ApplyRegularExpressionAttribute(OpenApiSchema schema, RegularExpressionAttribute regularExpressionAttribute)
289289
{

src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/SchemaGenerator.cs

+9-3
Original file line numberDiff line numberDiff line change
@@ -403,8 +403,8 @@ private OpenApiSchema CreateObjectSchema(DataContract dataContract, SchemaReposi
403403
var schema = new OpenApiSchema
404404
{
405405
Type = JsonSchemaTypes.Object,
406-
Properties = new Dictionary<string, IOpenApiSchema>(),
407-
Required = new SortedSet<string>(),
406+
Properties = [],
407+
Required = [],
408408
AdditionalPropertiesAllowed = false
409409
};
410410

@@ -492,6 +492,11 @@ private OpenApiSchema CreateObjectSchema(DataContract dataContract, SchemaReposi
492492
root.AllOf.Add(schema);
493493
}
494494

495+
if (schema.Required?.Count > 1)
496+
{
497+
schema.Required = [.. new SortedSet<string>(schema.Required)];
498+
}
499+
495500
return root;
496501
}
497502

@@ -542,7 +547,8 @@ private bool TryGetDiscriminatorFor(
542547
{
543548
if (GenerateConcreteSchema(knownTypeDataContract, schemaRepository) is OpenApiSchemaReference reference)
544549
{
545-
discriminator.Mapping.Add(discriminatorValue, reference.Reference.ReferenceV3);
550+
discriminator.Mapping ??= [];
551+
discriminator.Mapping.Add(discriminatorValue, reference);
546552
}
547553
}
548554
}

src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGenerator.cs

+21-19
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ static void SortSchema(IOpenApiSchema schema)
149149
{
150150
if (concrete.Required is { Count: > 1 } required)
151151
{
152-
concrete.Required = new SortedSet<string>(required);
152+
concrete.Required = [.. new SortedSet<string>(required)];
153153
}
154154

155155
if (concrete.AllOf is { Count: > 0 } allOf)
@@ -241,7 +241,7 @@ private async Task<OpenApiPaths> GeneratePathsAsync(
241241
OpenApiDocument document,
242242
IEnumerable<ApiDescription> apiDescriptions,
243243
SchemaRepository schemaRepository,
244-
Func<OpenApiDocument, IGrouping<string, ApiDescription>, SchemaRepository, Task<Dictionary<OperationType, OpenApiOperation>>> operationsGenerator)
244+
Func<OpenApiDocument, IGrouping<string, ApiDescription>, SchemaRepository, Task<Dictionary<HttpMethod, OpenApiOperation>>> operationsGenerator)
245245
{
246246
var apiDescriptionsByPath = apiDescriptions
247247
.OrderBy(_options.SortKeySelector)
@@ -285,7 +285,7 @@ private async Task<OpenApiPaths> GeneratePathsAsync(
285285
GenerateOperationsAsync);
286286
}
287287

288-
private IEnumerable<(OperationType, ApiDescription)> GetOperationsGroupedByMethod(
288+
private IEnumerable<(HttpMethod, ApiDescription)> GetOperationsGroupedByMethod(
289289
IEnumerable<ApiDescription> apiDescriptions)
290290
{
291291
return apiDescriptions
@@ -294,13 +294,13 @@ private async Task<OpenApiPaths> GeneratePathsAsync(
294294
.Select(PrepareGenerateOperation);
295295
}
296296

297-
private Dictionary<OperationType, OpenApiOperation> GenerateOperations(
297+
private Dictionary<HttpMethod, OpenApiOperation> GenerateOperations(
298298
OpenApiDocument document,
299299
IEnumerable<ApiDescription> apiDescriptions,
300300
SchemaRepository schemaRepository)
301301
{
302302
var apiDescriptionsByMethod = GetOperationsGroupedByMethod(apiDescriptions);
303-
var operations = new Dictionary<OperationType, OpenApiOperation>();
303+
var operations = new Dictionary<HttpMethod, OpenApiOperation>();
304304

305305
foreach ((var operationType, var description) in apiDescriptionsByMethod)
306306
{
@@ -310,13 +310,13 @@ private Dictionary<OperationType, OpenApiOperation> GenerateOperations(
310310
return operations;
311311
}
312312

313-
private async Task<Dictionary<OperationType, OpenApiOperation>> GenerateOperationsAsync(
313+
private async Task<Dictionary<HttpMethod, OpenApiOperation>> GenerateOperationsAsync(
314314
OpenApiDocument document,
315315
IEnumerable<ApiDescription> apiDescriptions,
316316
SchemaRepository schemaRepository)
317317
{
318318
var apiDescriptionsByMethod = GetOperationsGroupedByMethod(apiDescriptions);
319-
var operations = new Dictionary<OperationType, OpenApiOperation>();
319+
var operations = new Dictionary<HttpMethod, OpenApiOperation>();
320320

321321
foreach ((var operationType, var description) in apiDescriptionsByMethod)
322322
{
@@ -326,7 +326,7 @@ private async Task<Dictionary<OperationType, OpenApiOperation>> GenerateOperatio
326326
return operations;
327327
}
328328

329-
private (OperationType OperationType, ApiDescription ApiDescription) PrepareGenerateOperation(IGrouping<string, ApiDescription> group)
329+
private (HttpMethod OperationType, ApiDescription ApiDescription) PrepareGenerateOperation(IGrouping<string, ApiDescription> group)
330330
{
331331
var httpMethod = group.Key ?? throw new SwaggerGeneratorException(string.Format(
332332
"Ambiguous HTTP method for action - {0}. " +
@@ -583,7 +583,7 @@ private HashSet<OpenApiTagReference> GenerateOperationTags(OpenApiDocument docum
583583

584584
if (names.Length > 0)
585585
{
586-
document.Tags ??= new HashSet<OpenApiTag>();
586+
document.Tags ??= [];
587587
foreach (var name in names)
588588
{
589589
document.Tags.Add(new OpenApiTag { Name = name });
@@ -1025,7 +1025,7 @@ static OpenApiSchema GenerateSchemaForProperties(Dictionary<string, IOpenApiSche
10251025
{
10261026
Type = JsonSchemaTypes.Object,
10271027
Properties = properties,
1028-
Required = new SortedSet<string>(requiredPropertyNames)
1028+
Required = [.. new SortedSet<string>(requiredPropertyNames)],
10291029
};
10301030
}
10311031

@@ -1108,16 +1108,18 @@ private static bool IsFromFormAttributeUsedWithIFormFile(ApiParameterDescription
11081108
return fromFormAttribute != null && parameterInfo?.ParameterType == typeof(IFormFile);
11091109
}
11101110

1111-
private static readonly Dictionary<string, OperationType> OperationTypeMap = new(StringComparer.OrdinalIgnoreCase)
1111+
private static readonly Dictionary<string, HttpMethod> OperationTypeMap = new(StringComparer.OrdinalIgnoreCase)
11121112
{
1113-
["GET"] = OperationType.Get,
1114-
["PUT"] = OperationType.Put,
1115-
["POST"] = OperationType.Post,
1116-
["DELETE"] = OperationType.Delete,
1117-
["OPTIONS"] = OperationType.Options,
1118-
["HEAD"] = OperationType.Head,
1119-
["PATCH"] = OperationType.Patch,
1120-
["TRACE"] = OperationType.Trace,
1113+
["GET"] = HttpMethod.Get,
1114+
["PUT"] = HttpMethod.Put,
1115+
["POST"] = HttpMethod.Post,
1116+
["DELETE"] = HttpMethod.Delete,
1117+
["OPTIONS"] = HttpMethod.Options,
1118+
["HEAD"] = HttpMethod.Head,
1119+
#if NET
1120+
["PATCH"] = HttpMethod.Patch,
1121+
#endif
1122+
["TRACE"] = HttpMethod.Trace,
11211123
};
11221124

11231125
private static readonly Dictionary<BindingSource, ParameterLocation> ParameterLocationMap = new()

src/Swashbuckle.AspNetCore.SwaggerGen/XmlComments/XmlCommentsDocumentFilter.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
3232
var summaryNode = typeNode.SelectFirstChild(SummaryTag);
3333
if (summaryNode != null)
3434
{
35-
swaggerDoc.Tags ??= new HashSet<OpenApiTag>();
35+
swaggerDoc.Tags ??= [];
3636

3737
var name = nameAndType.Key;
3838
var tag = swaggerDoc.Tags.FirstOrDefault((p) => p?.Name == name);

0 commit comments

Comments
 (0)