From 8dd9b333437ba2efa1e50c7d420a7bdaf91a32ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Garc=C3=ADa=20de=20la=20Noceda=20Arg=C3=BCelles?= Date: Thu, 11 Jul 2024 00:13:55 +0200 Subject: [PATCH 1/2] Missing Encoding and RequiredProperties when IformFile withOpenApi --- .../SwaggerGenerator/SwaggerGenerator.cs | 28 +++++++++++-------- ...r_WebApi_swaggerRequestUri=v1.verified.txt | 16 +++++++++++ ...est.TypesAreRenderedCorrectly.verified.txt | 16 +++++++++++ .../SwaggerGenerator/SwaggerGeneratorTests.cs | 6 ++++ ...OpenApiOperationWithIFormFile.verified.txt | 7 ++++- ...rationWithIFormFileCollection.verified.txt | 7 ++++- 6 files changed, 67 insertions(+), 13 deletions(-) diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGenerator.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGenerator.cs index 665ab91966..a7ca2daa76 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGenerator.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGenerator.cs @@ -420,6 +420,7 @@ private OpenApiOperation GenerateOpenApiOperationFromMetadata(ApiDescription api { foreach (var content in requestContentTypes) { + content.Encoding = new Dictionary(); var requestParameters = apiDescription.ParameterDescriptions.Where(desc => desc.IsFromBody() || desc.IsFromForm()); var countOfParameters = requestParameters.Count(); if (countOfParameters > 0) @@ -431,7 +432,7 @@ private OpenApiOperation GenerateOpenApiOperationFromMetadata(ApiDescription api requestParameter.ModelMetadata.ModelType, schemaRepository, requestParameter.PropertyInfo(), - requestParameter.ParameterInfo())); + requestParameter.ParameterInfo()), content); } else { @@ -442,25 +443,30 @@ private OpenApiOperation GenerateOpenApiOperationFromMetadata(ApiDescription api s.ModelMetadata.ModelType, schemaRepository, s.PropertyInfo(), - s.ParameterInfo()))) + s.ParameterInfo()), content)) .ToList() }; } } - static OpenApiSchema GenerateSchemaIncludingFormFile(ApiParameterDescription apiParameterDescription, OpenApiSchema generatedSchema) + static OpenApiSchema GenerateSchemaIncludingFormFile(ApiParameterDescription apiParameterDescription, OpenApiSchema generatedSchema, OpenApiMediaType mediaType) { - if (generatedSchema.Reference is null - && ((generatedSchema.Type == "string" && generatedSchema.Format == "binary") || (generatedSchema.Type == "array" && generatedSchema.Items.Format == "binary"))) + if (generatedSchema.Reference is null && apiParameterDescription.IsFromForm()) { - return new OpenApiSchema() + mediaType.Encoding.Add(apiParameterDescription.Name, new OpenApiEncoding { Style = ParameterStyle.Form }); + if((generatedSchema.Type == "string" && generatedSchema.Format == "binary") + || (generatedSchema.Type == "array" && generatedSchema.Items.Type == "string" && generatedSchema.Items.Format == "binary")) { - Type = "object", - Properties = new Dictionary() + return new OpenApiSchema() { - [apiParameterDescription.Name] = generatedSchema - } - }; + Type = "object", + Properties = new Dictionary() + { + [apiParameterDescription.Name] = generatedSchema + }, + Required = apiParameterDescription.IsRequired ? new SortedSet() { apiParameterDescription.Name} : null + }; + } } return generatedSchema; } diff --git a/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.SwaggerEndpoint_ReturnsValidSwaggerJson_For_WebApi_swaggerRequestUri=v1.verified.txt b/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.SwaggerEndpoint_ReturnsValidSwaggerJson_For_WebApi_swaggerRequestUri=v1.verified.txt index c17e53c026..79c1b95f9a 100644 --- a/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.SwaggerEndpoint_ReturnsValidSwaggerJson_For_WebApi_swaggerRequestUri=v1.verified.txt +++ b/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.SwaggerEndpoint_ReturnsValidSwaggerJson_For_WebApi_swaggerRequestUri=v1.verified.txt @@ -128,6 +128,9 @@ "content": { "multipart/form-data": { "schema": { + "required": [ + "file" + ], "type": "object", "properties": { "file": { @@ -135,6 +138,11 @@ "format": "binary" } } + }, + "encoding": { + "file": { + "style": "form" + } } } }, @@ -163,6 +171,9 @@ "content": { "multipart/form-data": { "schema": { + "required": [ + "collection" + ], "type": "object", "properties": { "collection": { @@ -173,6 +184,11 @@ } } } + }, + "encoding": { + "collection": { + "style": "form" + } } } }, diff --git a/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.TypesAreRenderedCorrectly.verified.txt b/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.TypesAreRenderedCorrectly.verified.txt index c17e53c026..79c1b95f9a 100644 --- a/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.TypesAreRenderedCorrectly.verified.txt +++ b/test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerVerifyIntegrationTest.TypesAreRenderedCorrectly.verified.txt @@ -128,6 +128,9 @@ "content": { "multipart/form-data": { "schema": { + "required": [ + "file" + ], "type": "object", "properties": { "file": { @@ -135,6 +138,11 @@ "format": "binary" } } + }, + "encoding": { + "file": { + "style": "form" + } } } }, @@ -163,6 +171,9 @@ "content": { "multipart/form-data": { "schema": { + "required": [ + "collection" + ], "type": "object", "properties": { "collection": { @@ -173,6 +184,11 @@ } } } + }, + "encoding": { + "collection": { + "style": "form" + } } } }, diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGenerator/SwaggerGeneratorTests.cs b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGenerator/SwaggerGeneratorTests.cs index e3a7edb872..491237929d 100644 --- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGenerator/SwaggerGeneratorTests.cs +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGenerator/SwaggerGeneratorTests.cs @@ -2155,6 +2155,9 @@ public void GetSwagger_GenerateConsumesSchemas_ForProvidedOpenApiOperationWithIF Assert.NotNull(content.Value.Schema.Properties["param"]); Assert.Equal("string", content.Value.Schema.Properties["param"].Type); Assert.Equal("binary", content.Value.Schema.Properties["param"].Format); + Assert.NotNull(content.Value.Encoding); + Assert.NotNull(content.Value.Encoding["param"]); + Assert.Equal(ParameterStyle.Form, content.Value.Encoding["param"].Style); } [Fact] @@ -2216,6 +2219,9 @@ public void GetSwagger_GenerateConsumesSchemas_ForProvidedOpenApiOperationWithIF Assert.NotNull(content.Value.Schema.Properties["param"].Items); Assert.Equal("string", content.Value.Schema.Properties["param"].Items.Type); Assert.Equal("binary", content.Value.Schema.Properties["param"].Items.Format); + Assert.NotNull(content.Value.Encoding); + Assert.NotNull(content.Value.Encoding["param"]); + Assert.Equal(ParameterStyle.Form, content.Value.Encoding["param"].Style); } private static SwaggerGenerator Subject( diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.GetSwagger_GenerateConsumesSchemas_ForProvidedOpenApiOperationWithIFormFile.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.GetSwagger_GenerateConsumesSchemas_ForProvidedOpenApiOperationWithIFormFile.verified.txt index 22c76f1d64..5ee6d90317 100644 --- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.GetSwagger_GenerateConsumesSchemas_ForProvidedOpenApiOperationWithIFormFile.verified.txt +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.GetSwagger_GenerateConsumesSchemas_ForProvidedOpenApiOperationWithIFormFile.verified.txt @@ -33,6 +33,11 @@ Nullable: false, Deprecated: false, UnresolvedReference: false + }, + Encoding: { + param: { + Style: Form + } } } } @@ -44,5 +49,5 @@ } }, Components: {}, - HashCode: 3B411279DDA5AD71B248D9E65E29E2545971131294B8FB032C0EC91640277615B8D600D78530054A7DA3754611589518B2C9773BB48A813B9951B46DE633743A + HashCode: 7D034A2620C1D85B3AC60194DFA59693F727DE4704B2D02E124FDA37F843426C258EF2BEB84E6B8E8D315E23A4BCBE1F423B479E6CDF8AFFB8514D49B9A3CC9E } \ No newline at end of file diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.GetSwagger_GenerateConsumesSchemas_ForProvidedOpenApiOperationWithIFormFileCollection.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.GetSwagger_GenerateConsumesSchemas_ForProvidedOpenApiOperationWithIFormFileCollection.verified.txt index 014d0e2a7b..4ff258c0fd 100644 --- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.GetSwagger_GenerateConsumesSchemas_ForProvidedOpenApiOperationWithIFormFileCollection.verified.txt +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SwaggerGeneratorVerifyTests/SwaggerGeneratorVerifyTests.GetSwagger_GenerateConsumesSchemas_ForProvidedOpenApiOperationWithIFormFileCollection.verified.txt @@ -42,6 +42,11 @@ Nullable: false, Deprecated: false, UnresolvedReference: false + }, + Encoding: { + param: { + Style: Form + } } } } @@ -53,5 +58,5 @@ } }, Components: {}, - HashCode: 64312D7E174EFA8B92E7869E39FD7367BB6A464F0C5E8A72D0B010AE96AAE157EE91BC02BEDFEC2B01CCC6BAA4E7FA79156782C09D435428AE8F732D3C9EB1B9 + HashCode: 073D8B8E67D5100DD8AF06EC69A3C02B8DBF29E46621ED6EB590DEA519F2C8941398F6B95292D891CC4E18C2F4D5D38A8F904545CFFC219E4FF4613AD605E5A5 } \ No newline at end of file From 8f22aaaa31fae85cf61c3b1d1009fc82a5481456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Garc=C3=ADa=20de=20la=20Noceda=20Arg=C3=BCelles?= Date: Thu, 11 Jul 2024 00:23:48 +0200 Subject: [PATCH 2/2] Address PR feedback --- .../SwaggerGenerator/SwaggerGenerator.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGenerator.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGenerator.cs index a7ca2daa76..bd31295eec 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGenerator.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGenerator.cs @@ -454,7 +454,7 @@ static OpenApiSchema GenerateSchemaIncludingFormFile(ApiParameterDescription api if (generatedSchema.Reference is null && apiParameterDescription.IsFromForm()) { mediaType.Encoding.Add(apiParameterDescription.Name, new OpenApiEncoding { Style = ParameterStyle.Form }); - if((generatedSchema.Type == "string" && generatedSchema.Format == "binary") + if ((generatedSchema.Type == "string" && generatedSchema.Format == "binary") || (generatedSchema.Type == "array" && generatedSchema.Items.Type == "string" && generatedSchema.Items.Format == "binary")) { return new OpenApiSchema() @@ -464,7 +464,7 @@ static OpenApiSchema GenerateSchemaIncludingFormFile(ApiParameterDescription api { [apiParameterDescription.Name] = generatedSchema }, - Required = apiParameterDescription.IsRequired ? new SortedSet() { apiParameterDescription.Name} : null + Required = apiParameterDescription.IsRequired ? new SortedSet() { apiParameterDescription.Name } : null }; } }