diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index c5e4ca3d4..a3976f1a8 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "2.3.2"
+ ".": "2.3.3"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee0c0d4ed..5ca0751e8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## [2.3.3](https://github.com/microsoft/OpenAPI.NET/compare/v2.3.2...v2.3.3) (2025-10-02)
+
+
+### Bug Fixes
+
+* typo in allowReserved property name for deserialization ([1633453](https://github.com/microsoft/OpenAPI.NET/commit/16334536dcb5182f26c0d58463bd15a124dd1505))
+* typo in allowReserved property name for deserialization ([f7e34be](https://github.com/microsoft/OpenAPI.NET/commit/f7e34be28566a4f714d43667f8c43be7159d27a2))
+
## [2.3.2](https://github.com/microsoft/OpenAPI.NET/compare/v2.3.1...v2.3.2) (2025-09-19)
diff --git a/Directory.Build.props b/Directory.Build.props
index 9e0c6a8d6..d61db6d94 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -12,7 +12,7 @@
https://github.com/Microsoft/OpenAPI.NET
© Microsoft Corporation. All rights reserved.
OpenAPI .NET
- 2.3.2
+ 2.3.3
diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs
index ec7f0cfdb..7ef6b2a0c 100644
--- a/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs
+++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs
@@ -87,6 +87,12 @@ internal static partial class OpenApiV3Deserializer
"schema",
(o, n, t) => o.Schema = LoadSchema(n, t)
},
+ {
+ "content", (o, n, t) =>
+ {
+ o.Content = n.CreateMap(LoadMediaType, t);
+ }
+ },
{
"examples",
(o, n, t) => o.Examples = n.CreateMap(LoadExample, t)
diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs
index 6474dc96b..3ed06d641 100644
--- a/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs
+++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs
@@ -1,76 +1,74 @@
using System;
-namespace Microsoft.OpenApi.Reader.V31
+namespace Microsoft.OpenApi.Reader.V31;
+///
+/// Class containing logic to deserialize Open API V31 document into
+/// runtime Open API object model.
+///
+internal static partial class OpenApiV31Deserializer
{
- ///
- /// Class containing logic to deserialize Open API V31 document into
- /// runtime Open API object model.
- ///
- internal static partial class OpenApiV31Deserializer
+ private static readonly FixedFieldMap _encodingFixedFields = new()
{
- private static readonly FixedFieldMap _encodingFixedFields = new()
{
+ "contentType", (o, n, _) =>
{
- "contentType", (o, n, _) =>
- {
- o.ContentType = n.GetScalarValue();
- }
- },
+ o.ContentType = n.GetScalarValue();
+ }
+ },
+ {
+ "headers", (o, n, t) =>
{
- "headers", (o, n, t) =>
- {
- o.Headers = n.CreateMap(LoadHeader, t);
- }
- },
+ o.Headers = n.CreateMap(LoadHeader, t);
+ }
+ },
+ {
+ "style", (o, n, _) =>
{
- "style", (o, n, _) =>
+ if(!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var style))
{
- if(!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var style))
- {
- return;
- }
- o.Style = style;
+ return;
}
- },
+ o.Style = style;
+ }
+ },
+ {
+ "explode", (o, n, _) =>
{
- "explode", (o, n, _) =>
+ var explode = n.GetScalarValue();
+ if (explode is not null)
{
- var explode = n.GetScalarValue();
- if (explode is not null)
- {
- o.Explode = bool.Parse(explode);
- }
- }
- },
+ o.Explode = bool.Parse(explode);
+ }
+ }
+ },
+ {
+ "allowReserved", (o, n, _) =>
{
- "allowReserved", (o, n, _) =>
+ var allowReserved = n.GetScalarValue();
+ if (allowReserved is not null)
{
- var allowReserved = n.GetScalarValue();
- if (allowReserved is not null)
- {
- o.AllowReserved = bool.Parse(allowReserved);
- }
+ o.AllowReserved = bool.Parse(allowReserved);
}
- },
- };
-
- private static readonly PatternFieldMap _encodingPatternFields =
- new()
- {
- {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))}
- };
+ }
+ },
+ };
- public static OpenApiEncoding LoadEncoding(ParseNode node, OpenApiDocument hostDocument)
+ private static readonly PatternFieldMap _encodingPatternFields =
+ new()
{
- var mapNode = node.CheckMapNode("encoding");
+ {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))}
+ };
- var encoding = new OpenApiEncoding();
- foreach (var property in mapNode)
- {
- property.ParseField(encoding, _encodingFixedFields, _encodingPatternFields, hostDocument);
- }
+ public static OpenApiEncoding LoadEncoding(ParseNode node, OpenApiDocument hostDocument)
+ {
+ var mapNode = node.CheckMapNode("encoding");
- return encoding;
+ var encoding = new OpenApiEncoding();
+ foreach (var property in mapNode)
+ {
+ property.ParseField(encoding, _encodingFixedFields, _encodingPatternFields, hostDocument);
}
+
+ return encoding;
}
}
diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs
index 6ed2fe97f..208899b54 100644
--- a/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs
+++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs
@@ -87,6 +87,12 @@ internal static partial class OpenApiV31Deserializer
o.Schema = LoadSchema(n, t);
}
},
+ {
+ "content", (o, n, t) =>
+ {
+ o.Content = n.CreateMap(LoadMediaType, t);
+ }
+ },
{
"examples", (o, n, t) =>
{
diff --git a/test/Microsoft.OpenApi.Hidi.Tests/Microsoft.OpenApi.Hidi.Tests.csproj b/test/Microsoft.OpenApi.Hidi.Tests/Microsoft.OpenApi.Hidi.Tests.csproj
index 20f6516a7..33656177d 100644
--- a/test/Microsoft.OpenApi.Hidi.Tests/Microsoft.OpenApi.Hidi.Tests.csproj
+++ b/test/Microsoft.OpenApi.Hidi.Tests/Microsoft.OpenApi.Hidi.Tests.csproj
@@ -14,7 +14,7 @@
-
+
diff --git a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj
index bfe4ffc17..8e19f7370 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj
+++ b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj
@@ -17,7 +17,7 @@
-
+
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiEncodingTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiEncodingTests.cs
new file mode 100644
index 000000000..6a03ea015
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiEncodingTests.cs
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license.
+
+using System.IO;
+using System.Threading.Tasks;
+using Microsoft.OpenApi.Reader;
+using Xunit;
+
+namespace Microsoft.OpenApi.Readers.Tests.V31Tests
+{
+ [Collection("DefaultSettings")]
+ public class OpenApiEncodingTests
+ {
+ private const string SampleFolderPath = "V31Tests/Samples/OpenApiEncoding/";
+
+ [Fact]
+ public async Task ParseEncodingWithAllowReservedShouldSucceed()
+ {
+ // Act
+ var encoding = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "encodingWithAllowReserved.yaml"), OpenApiSpecVersion.OpenApi3_1, new(), SettingsFixture.ReaderSettings);
+
+ // Assert
+ Assert.Equivalent(
+ new OpenApiEncoding
+ {
+ ContentType = "application/x-www-form-urlencoded",
+ Style = ParameterStyle.Form,
+ Explode = true,
+ AllowReserved = true
+ }, encoding);
+ }
+ }
+}
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiHeaderTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiHeaderTests.cs
new file mode 100644
index 000000000..60ec248a0
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiHeaderTests.cs
@@ -0,0 +1,136 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license.
+
+using System.Collections.Generic;
+using System.IO;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Microsoft.OpenApi.Reader;
+using Xunit;
+
+namespace Microsoft.OpenApi.Readers.Tests.V31Tests
+{
+ [Collection("DefaultSettings")]
+ public class OpenApiHeaderTests
+ {
+ private const string SampleFolderPath = "V31Tests/Samples/OpenApiHeader/";
+
+ [Fact]
+ public async Task ParseBasicHeaderShouldSucceed()
+ {
+ // Arrange
+ using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "basicHeader.yaml"));
+
+ // Act
+ var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_1, new(), settings: SettingsFixture.ReaderSettings);
+
+ // Assert
+ Assert.Equivalent(
+ new OpenApiHeader
+ {
+ Description = "The number of allowed requests in the current period",
+ Schema = new OpenApiSchema()
+ {
+ Type = JsonSchemaType.Integer
+ }
+ }, header);
+ }
+
+ [Fact]
+ public async Task ParseHeaderWithContentShouldSucceed()
+ {
+ // Arrange
+ using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "headerWithContent.yaml"));
+
+ // Act
+ var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_1, new(), settings: SettingsFixture.ReaderSettings);
+
+ // Assert
+ Assert.Equivalent(
+ new OpenApiHeader
+ {
+ Description = "A complex header with content",
+ Content = new Dictionary()
+ {
+ ["application/json"] = new()
+ {
+ Schema = new OpenApiSchema()
+ {
+ Type = JsonSchemaType.Object,
+ Properties = new Dictionary()
+ {
+ ["timestamp"] = new OpenApiSchema()
+ {
+ Type = JsonSchemaType.String,
+ Format = "date-time"
+ },
+ ["value"] = new OpenApiSchema()
+ {
+ Type = JsonSchemaType.Integer
+ }
+ }
+ }
+ }
+ }
+ }, header);
+ }
+
+ [Fact]
+ public async Task ParseHeaderWithMultipleContentTypesShouldSucceed()
+ {
+ // Arrange
+ using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "headerWithMultipleContentTypes.yaml"));
+
+ // Act
+ var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_1, new(), settings: SettingsFixture.ReaderSettings);
+
+ // Assert
+ Assert.Equivalent(
+ new OpenApiHeader
+ {
+ Description = "A header that accepts multiple content types",
+ Content = new Dictionary()
+ {
+ ["application/json"] = new()
+ {
+ Schema = new OpenApiSchema()
+ {
+ Type = JsonSchemaType.Object,
+ Properties = new Dictionary()
+ {
+ ["data"] = new OpenApiSchema()
+ {
+ Type = JsonSchemaType.String
+ }
+ }
+ }
+ },
+ ["text/plain"] = new()
+ {
+ Schema = new OpenApiSchema()
+ {
+ Type = JsonSchemaType.String
+ }
+ }
+ }
+ }, header);
+ }
+
+ [Fact]
+ public async Task ParseHeaderWithStyleAndContentShouldPreferContent()
+ {
+ // Arrange
+ using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "headerWithStyleAndContent.yaml"));
+
+ // Act
+ var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_1, new(), settings: SettingsFixture.ReaderSettings);
+
+ // Assert
+ // Both content and style can be present, content takes precedence for serialization behavior
+ Assert.NotNull(header.Content);
+ Assert.Single(header.Content);
+ Assert.True(header.Content.ContainsKey("application/json"));
+ Assert.Equal(ParameterStyle.Simple, header.Style); // Style can still be present
+ }
+ }
+}
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiEncoding/encodingWithAllowReserved.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiEncoding/encodingWithAllowReserved.yaml
new file mode 100644
index 000000000..fcb6c1063
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiEncoding/encodingWithAllowReserved.yaml
@@ -0,0 +1,5 @@
+# https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#encodingObject
+contentType: application/x-www-form-urlencoded
+style: form
+explode: true
+allowReserved: true
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiHeader/basicHeader.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiHeader/basicHeader.yaml
new file mode 100644
index 000000000..015804759
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiHeader/basicHeader.yaml
@@ -0,0 +1,3 @@
+description: "The number of allowed requests in the current period"
+schema:
+ type: integer
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiHeader/headerWithContent.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiHeader/headerWithContent.yaml
new file mode 100644
index 000000000..dc2df9ffd
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiHeader/headerWithContent.yaml
@@ -0,0 +1,11 @@
+description: "A complex header with content"
+content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ timestamp:
+ type: string
+ format: date-time
+ value:
+ type: integer
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiHeader/headerWithMultipleContentTypes.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiHeader/headerWithMultipleContentTypes.yaml
new file mode 100644
index 000000000..82c74ea60
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiHeader/headerWithMultipleContentTypes.yaml
@@ -0,0 +1,11 @@
+description: "A header that accepts multiple content types"
+content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ data:
+ type: string
+ text/plain:
+ schema:
+ type: string
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiHeader/headerWithStyleAndContent.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiHeader/headerWithStyleAndContent.yaml
new file mode 100644
index 000000000..fbe176683
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiHeader/headerWithStyleAndContent.yaml
@@ -0,0 +1,11 @@
+description: "A header with both style and content (content should take precedence)"
+style: simple
+schema:
+ type: string
+content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ value:
+ type: string
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiEncodingTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiEncodingTests.cs
index db78cc0c7..0c0c4e96f 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiEncodingTests.cs
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiEncodingTests.cs
@@ -55,5 +55,22 @@ public async Task ParseAdvancedEncodingShouldSucceed()
}
}, encoding);
}
+
+ [Fact]
+ public async Task ParseEncodingWithAllowReservedShouldSucceed()
+ {
+ // Act
+ var encoding = await OpenApiModelFactory.LoadAsync(Path.Combine(SampleFolderPath, "encodingWithAllowReserved.yaml"), OpenApiSpecVersion.OpenApi3_0, new(), SettingsFixture.ReaderSettings);
+
+ // Assert
+ Assert.Equivalent(
+ new OpenApiEncoding
+ {
+ ContentType = "application/x-www-form-urlencoded",
+ Style = ParameterStyle.Form,
+ Explode = true,
+ AllowReserved = true
+ }, encoding);
+ }
}
}
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiHeaderTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiHeaderTests.cs
new file mode 100644
index 000000000..ba0ab49d3
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiHeaderTests.cs
@@ -0,0 +1,136 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license.
+
+using System.Collections.Generic;
+using System.IO;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Microsoft.OpenApi.Reader;
+using Xunit;
+
+namespace Microsoft.OpenApi.Readers.Tests.V3Tests
+{
+ [Collection("DefaultSettings")]
+ public class OpenApiHeaderTests
+ {
+ private const string SampleFolderPath = "V3Tests/Samples/OpenApiHeader/";
+
+ [Fact]
+ public async Task ParseBasicHeaderShouldSucceed()
+ {
+ // Arrange
+ using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "basicHeader.yaml"));
+
+ // Act
+ var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings);
+
+ // Assert
+ Assert.Equivalent(
+ new OpenApiHeader
+ {
+ Description = "The number of allowed requests in the current period",
+ Schema = new OpenApiSchema()
+ {
+ Type = JsonSchemaType.Integer
+ }
+ }, header);
+ }
+
+ [Fact]
+ public async Task ParseHeaderWithContentShouldSucceed()
+ {
+ // Arrange
+ using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "headerWithContent.yaml"));
+
+ // Act
+ var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings);
+
+ // Assert
+ Assert.Equivalent(
+ new OpenApiHeader
+ {
+ Description = "A complex header with content",
+ Content = new Dictionary()
+ {
+ ["application/json"] = new()
+ {
+ Schema = new OpenApiSchema()
+ {
+ Type = JsonSchemaType.Object,
+ Properties = new Dictionary()
+ {
+ ["timestamp"] = new OpenApiSchema()
+ {
+ Type = JsonSchemaType.String,
+ Format = "date-time"
+ },
+ ["value"] = new OpenApiSchema()
+ {
+ Type = JsonSchemaType.Integer
+ }
+ }
+ }
+ }
+ }
+ }, header);
+ }
+
+ [Fact]
+ public async Task ParseHeaderWithMultipleContentTypesShouldSucceed()
+ {
+ // Arrange
+ using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "headerWithMultipleContentTypes.yaml"));
+
+ // Act
+ var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings);
+
+ // Assert
+ Assert.Equivalent(
+ new OpenApiHeader
+ {
+ Description = "A header that accepts multiple content types",
+ Content = new Dictionary()
+ {
+ ["application/json"] = new()
+ {
+ Schema = new OpenApiSchema()
+ {
+ Type = JsonSchemaType.Object,
+ Properties = new Dictionary()
+ {
+ ["data"] = new OpenApiSchema()
+ {
+ Type = JsonSchemaType.String
+ }
+ }
+ }
+ },
+ ["text/plain"] = new()
+ {
+ Schema = new OpenApiSchema()
+ {
+ Type = JsonSchemaType.String
+ }
+ }
+ }
+ }, header);
+ }
+
+ [Fact]
+ public async Task ParseHeaderWithStyleAndContentShouldPreferContent()
+ {
+ // Arrange
+ using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "headerWithStyleAndContent.yaml"));
+
+ // Act
+ var header = await OpenApiModelFactory.LoadAsync(stream, OpenApiSpecVersion.OpenApi3_0, new(), settings: SettingsFixture.ReaderSettings);
+
+ // Assert
+ // Both content and style can be present, content takes precedence for serialization behavior
+ Assert.NotNull(header.Content);
+ Assert.Single(header.Content);
+ Assert.True(header.Content.ContainsKey("application/json"));
+ Assert.Equal(ParameterStyle.Simple, header.Style); // Style can still be present
+ }
+ }
+}
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiEncoding/encodingWithAllowReserved.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiEncoding/encodingWithAllowReserved.yaml
new file mode 100644
index 000000000..259ba7fdf
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiEncoding/encodingWithAllowReserved.yaml
@@ -0,0 +1,5 @@
+# https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#encodingObject
+contentType: application/x-www-form-urlencoded
+style: form
+explode: true
+allowReserved: true
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiHeader/basicHeader.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiHeader/basicHeader.yaml
new file mode 100644
index 000000000..015804759
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiHeader/basicHeader.yaml
@@ -0,0 +1,3 @@
+description: "The number of allowed requests in the current period"
+schema:
+ type: integer
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiHeader/headerWithContent.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiHeader/headerWithContent.yaml
new file mode 100644
index 000000000..dc2df9ffd
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiHeader/headerWithContent.yaml
@@ -0,0 +1,11 @@
+description: "A complex header with content"
+content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ timestamp:
+ type: string
+ format: date-time
+ value:
+ type: integer
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiHeader/headerWithMultipleContentTypes.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiHeader/headerWithMultipleContentTypes.yaml
new file mode 100644
index 000000000..82c74ea60
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiHeader/headerWithMultipleContentTypes.yaml
@@ -0,0 +1,11 @@
+description: "A header that accepts multiple content types"
+content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ data:
+ type: string
+ text/plain:
+ schema:
+ type: string
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiHeader/headerWithStyleAndContent.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiHeader/headerWithStyleAndContent.yaml
new file mode 100644
index 000000000..fbe176683
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiHeader/headerWithStyleAndContent.yaml
@@ -0,0 +1,11 @@
+description: "A header with both style and content (content should take precedence)"
+style: simple
+schema:
+ type: string
+content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ value:
+ type: string
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj b/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj
index c833527fd..763db67d6 100644
--- a/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj
+++ b/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj
@@ -11,7 +11,7 @@
-
+