Skip to content

Commit 34b0f77

Browse files
committed
Serialize explode value properly on parameters with style "form"
When a parameter has the style set to "form" and explode set to false, the v3 serializer will not write out the value for explode. Swagger UI then defaults the explode value to true, since it is not specified and that is the correct default value when the style is set to "form". The OpenAPI spec for this is right around here: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#fixed-fields-10
1 parent 5742db6 commit 34b0f77

File tree

2 files changed

+115
-1
lines changed

2 files changed

+115
-1
lines changed

src/Microsoft.OpenApi/Models/OpenApiParameter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ public void SerializeAsV3WithoutReference(IOpenApiWriter writer)
177177
writer.WriteProperty(OpenApiConstants.Style, Style?.GetDisplayName());
178178

179179
// explode
180-
writer.WriteProperty(OpenApiConstants.Explode, Explode, false);
180+
writer.WriteProperty(OpenApiConstants.Explode, Explode, Style.HasValue && Style.Value == ParameterStyle.Form);
181181

182182
// allowReserved
183183
writer.WriteProperty(OpenApiConstants.AllowReserved, AllowReserved, false);

test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.cs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Globalization;
66
using System.IO;
77
using FluentAssertions;
8+
using Microsoft.OpenApi.Any;
89
using Microsoft.OpenApi.Extensions;
910
using Microsoft.OpenApi.Models;
1011
using Microsoft.OpenApi.Writers;
@@ -58,6 +59,50 @@ public class OpenApiParameterTests
5859
}
5960
};
6061

62+
public static OpenApiParameter ParameterWithFormStyleAndExplodeFalse = new OpenApiParameter
63+
{
64+
Name = "name1",
65+
In = ParameterLocation.Query,
66+
Description = "description1",
67+
Style = ParameterStyle.Form,
68+
Explode = false,
69+
Schema = new OpenApiSchema
70+
{
71+
Type = "array",
72+
Items = new OpenApiSchema
73+
{
74+
Enum = new List<IOpenApiAny>
75+
{
76+
new OpenApiString("value1"),
77+
new OpenApiString("value2")
78+
}
79+
}
80+
}
81+
82+
};
83+
84+
public static OpenApiParameter ParameterWithFormStyleAndExplodeTrue = new OpenApiParameter
85+
{
86+
Name = "name1",
87+
In = ParameterLocation.Query,
88+
Description = "description1",
89+
Style = ParameterStyle.Form,
90+
Explode = true,
91+
Schema = new OpenApiSchema
92+
{
93+
Type = "array",
94+
Items = new OpenApiSchema
95+
{
96+
Enum = new List<IOpenApiAny>
97+
{
98+
new OpenApiString("value1"),
99+
new OpenApiString("value2")
100+
}
101+
}
102+
}
103+
104+
};
105+
61106
public static OpenApiParameter AdvancedHeaderParameterWithSchemaReference = new OpenApiParameter
62107
{
63108
Name = "name1",
@@ -309,5 +354,74 @@ public void SerializeParameterWithSchemaTypeObjectAsV2JsonWorks()
309354
expected = expected.MakeLineBreaksEnvironmentNeutral();
310355
actual.Should().Be(expected);
311356
}
357+
358+
[Fact]
359+
public void SerializeParameterWithFormStyleAndExplodeFalseWorks()
360+
{
361+
// Arrange
362+
var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture);
363+
var writer = new OpenApiJsonWriter(outputStringWriter);
364+
var expected =
365+
@"{
366+
""name"": ""name1"",
367+
""in"": ""query"",
368+
""description"": ""description1"",
369+
""style"": ""form"",
370+
""explode"": false,
371+
""schema"": {
372+
""type"": ""array"",
373+
""items"": {
374+
""enum"": [
375+
""value1"",
376+
""value2""
377+
]
378+
}
379+
}
380+
}";
381+
382+
// Act
383+
ParameterWithFormStyleAndExplodeFalse.SerializeAsV3WithoutReference(writer);
384+
writer.Flush();
385+
var actual = outputStringWriter.GetStringBuilder().ToString();
386+
387+
// Assert
388+
actual = actual.MakeLineBreaksEnvironmentNeutral();
389+
expected = expected.MakeLineBreaksEnvironmentNeutral();
390+
actual.Should().Be(expected);
391+
}
392+
393+
[Fact]
394+
public void SerializeParameterWithFormStyleAndExplodeTrueWorks()
395+
{
396+
// Arrange
397+
var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture);
398+
var writer = new OpenApiJsonWriter(outputStringWriter);
399+
var expected =
400+
@"{
401+
""name"": ""name1"",
402+
""in"": ""query"",
403+
""description"": ""description1"",
404+
""style"": ""form"",
405+
""schema"": {
406+
""type"": ""array"",
407+
""items"": {
408+
""enum"": [
409+
""value1"",
410+
""value2""
411+
]
412+
}
413+
}
414+
}";
415+
416+
// Act
417+
ParameterWithFormStyleAndExplodeTrue.SerializeAsV3WithoutReference(writer);
418+
writer.Flush();
419+
var actual = outputStringWriter.GetStringBuilder().ToString();
420+
421+
// Assert
422+
actual = actual.MakeLineBreaksEnvironmentNeutral();
423+
expected = expected.MakeLineBreaksEnvironmentNeutral();
424+
actual.Should().Be(expected);
425+
}
312426
}
313427
}

0 commit comments

Comments
 (0)