Skip to content

Do not ignore multiple types when serializing to 3.0 - #2960

Merged
Gavin Barron (gavinbarron) merged 8 commits into
microsoft:mainfrom
Youssef1313:dev/ygerges/multiple-types-3
Aug 7, 2026
Merged

Gavin Barron (gavinbarron) merged 8 commits into
microsoft:mainfrom
Youssef1313:dev/ygerges/multiple-types-3

Conversation

@Youssef1313

@Youssef1313 Youssef Fahmy (Youssef1313) commented Jul 15, 2026 •

Copy link
Copy Markdown
Member

Fixes #2939

  • The change to ToSingleIdentifier is only a simplification to make it easier to read.
  • Type serialization is now split to two path to be easier to read, especially that 3.0 needs more parameters/info than 2.0.
  • The behavior of 2.0 is maintained as-is, no change there
  • Previously, in 3.0, we ignored when Type had multiple values (e.g, String and Integer). This is now handled using oneOf or anyOf (whichever isn't used by the current schema already). If both are used, we ignore as it we used to in the past.
  • The general idea here is:
    1. We take the Type.
    2. We remove Null from it (if it exists).
    3. If, after removing null, we have a single type, we simply emit it, and conditionally emit nullable: true depending on whether null was existing. This is the same as the existing behavior.
    4. If, after removing null, we have more than one type, we create a oneOf/anyOf with children schemas handling each type individually.
  • The reason around all that is that because type only supports a single value when using OpenApi 3.0.

For context: https://spec.openapis.org/oas/v3.0.4.html#json-schema-keywords

The following keywords are taken from the JSON Schema definition but their definitions were adjusted to the OpenAPI Specification.
type - Value MUST be a string. Multiple types via an array are not supported.

@Youssef1313
Youssef Fahmy (Youssef1313) marked this pull request as ready for review July 15, 2026 11:36
@Youssef1313
Youssef Fahmy (Youssef1313) requested a review from a team as a code owner July 15, 2026 11:36

@baywet Vincent Biret (baywet) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this kind of normalization should not be done during serialization, but rather through a walker which would be called before serialization.

See #808 and other related issues.

Case in point, we've had to revert some of the normalization done for null/nullable (to oneOf) in #2933

Copilot AI lite review requested due to automatic review settings July 30, 2026 07:58

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request updates OpenApiSchema JSON serialization to properly represent schemas with multiple JsonSchemaType flags when targeting OpenAPI 3.0, emitting anyOf/oneOf (when possible) instead of silently ignoring additional types, and adds coverage to validate the new behavior.

Changes:

  • Split type serialization logic between OpenAPI 2.0 and OpenAPI 3.0+ paths, adding 3.0-specific handling for multi-type schemas via anyOf/oneOf.
  • Add comprehensive unit tests covering multi-type combinations (with/without null, and with existing oneOf/anyOf present).
  • Simplify ToSingleIdentifier by using a lookup and providing a clearer exception for unexpected values.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs Adds tests validating multi-type serialization behavior for OpenAPI 3.0 across multiple composition scenarios.
src/Microsoft.OpenApi/Models/OpenApiSchema.cs Refactors and extends type serialization to support multi-type handling in 3.0 using anyOf/oneOf, keeping 2.0 behavior unchanged.
src/Microsoft.OpenApi/Extensions/OpenApiTypeMapper.cs Updates ToSingleIdentifier to use a lookup and throw a clearer exception for unexpected inputs.
Comments suppressed due to low confidence (1)

src/Microsoft.OpenApi/Models/OpenApiSchema.cs:1091

  • In the v3.1+ path, TrySerializeTypePropertyForVersion3AndLater also assumes Enum.GetValues() will match at least one flag in the provided Type. If Type is 0 or contains only unknown bits, array will be empty and array[0] will throw IndexOutOfRangeException. Add an empty-array guard and return false when no valid flags are present.
                var array = (from JsonSchemaType flag in jsonSchemaTypeValues
                                        where type.HasFlag(flag)
                                        select flag).ToArray();

                if (array.Length > 1)
                {
                    writer.WriteOptionalCollection(OpenApiConstants.Type, array, (w, s) => w.WriteValue(s.ToSingleIdentifier()));
                }
                else
                {
                    writer.WriteProperty(OpenApiConstants.Type, array[0].ToSingleIdentifier());
                }

@Youssef1313

Youssef Fahmy (Youssef1313) commented Jul 30, 2026 •

Copy link
Copy Markdown
Member Author

I believe this kind of normalization should not be done during serialization, but rather through a walker which would be called before serialization.

Given the investigations I did for #2967, I think it's fine for us to continue ensuring, as much as possible, that we produce semantically equivalent document for all versions. The cases presented in #2967 fall into two groups:

  • user bug (e.g, the Swashbuckle bug, or the JsonApiDotNetCore bug)
  • deserialization bugs on our side, which we can simply fix.

I don't believe there is a need for a new public API to do the semantic transformations, and I don't think all transformations we might want to do in future will be representable in the object model. So we will end up with logic scattered between dedicated walkers and in the serialization itself. We shouldn't need to pay additional performance cost for deep cloning the whole document as well.

In all cases, we can always decide to move the logic to a walker in the future, if really necessary.

Copilot AI review requested due to automatic review settings August 4, 2026 06:57

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (4)

src/Microsoft.OpenApi/Models/OpenApiSchema.cs:1088

  • In the OpenAPI 3.1+ branch, array[0] is used when array.Length <= 1. If Type is 0 or contains no known flags, array will be empty and this will throw IndexOutOfRangeException.
                }
                else
                {
                    writer.WriteProperty(OpenApiConstants.Type, array[0].ToSingleIdentifier());
                }

src/Microsoft.OpenApi/Models/OpenApiSchema.cs:1073

  • arrayWithoutNull[0] is accessed without guarding for arrayWithoutNull.Length == 0. If Type is set to an unexpected value (e.g., 0 / no flags, or only unknown bits), this will throw IndexOutOfRangeException during OpenAPI 3.0 serialization.
                else
                {
                    writer.WriteProperty(OpenApiConstants.Type, arrayWithoutNull[0].ToSingleIdentifier());
                    return;
                }

src/Microsoft.OpenApi/Models/OpenApiSchema.cs:1053

  • For OpenAPI 3.0, when Type includes null and multiple non-null types, this path represents null by adding a child schema with Type = Null into anyOf/oneOf. However SerializeNullable will still emit top-level nullable: true whenever HasNullType is true, even though there is no top-level type in that case. This produces redundant/ineffective output and contradicts the new tests that expect no nullable when null is represented via anyOf/oneOf.

This issue also appears in the following locations of the same file:

  • line 1069
  • line 1084
                // - If we have more than one type (excluding null), we have to use anyOf/oneOf.
                // - If we have exactly one type alone (without null), we emit the type property.
                // - If we have exactly one non-null type and also we have the null type, we emit the type property and nullable: true (handled in SerializeNullable)
                if (arrayWithoutNull.Length > 1)

src/Microsoft.OpenApi/Models/OpenApiSchema.cs:1029

  • This XML doc uses a <returns> block, but the method returns void. Either remove the <returns> documentation or change the method signature to return a value (and use it at the call site).
        /// <returns>
        /// true if the Type was serializable using "type" property, and false if
        /// it serialized using anyOf/oneOf or if it couldn't be serialized at all.
        /// </returns>

Copilot AI review requested due to automatic review settings August 4, 2026 07:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Suppressed comments (5)

test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaV30CompatibilityTests.cs:147

  • The test name says it "OmitsType", but the updated expected JSON now writes multiple types via anyOf (and also keeps nullable). Renaming the test would better match the behavior being asserted.
        public async Task SerializeMultipleNonNullTypesWithNullAsV3OmitsTypeButKeepsNullable()

src/Microsoft.OpenApi/Models/OpenApiSchema.cs:1029

  • XML documentation has a section describing a boolean return value, but SerializeTypePropertyForVersion3AndLater returns void. This makes the docs misleading for future maintainers.
        /// <summary>
        /// Tries to serialize the "type" property for OpenAPI v3 and later versions.
        /// </summary>
        /// <returns>
        /// true if the Type was serializable using "type" property, and false if
        /// it serialized using anyOf/oneOf or if it couldn't be serialized at all.
        /// </returns>

src/Microsoft.OpenApi/Models/OpenApiSchema.cs:1048

  • For OpenAPI 3.0, if Type is set to an empty flags value (e.g., (JsonSchemaType)0), typeWithoutNull will produce no flags and arrayWithoutNull will be empty. The current code then falls into the single-type branch and indexes arrayWithoutNull[0], which will throw IndexOutOfRangeException.
                var typeWithoutNull = type & ~JsonSchemaType.Null;
                var hasNull = typeWithoutNull != type;
                var arrayWithoutNull = (from JsonSchemaType flag in jsonSchemaTypeValues
                                        where typeWithoutNull.HasFlag(flag)
                                        select flag).ToArray();

src/Microsoft.OpenApi/Models/OpenApiSchema.cs:1079

  • For OpenAPI versions other than 3.0, if Type is an empty flags value ((JsonSchemaType)0), the computed array will be empty and the code will index array[0], throwing IndexOutOfRangeException.
                var array = (from JsonSchemaType flag in jsonSchemaTypeValues
                                        where type.HasFlag(flag)
                                        select flag).ToArray();

test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaV30CompatibilityTests.cs:121

  • The test name says it "OmitsType", but the updated expected JSON now writes multiple types via anyOf. Renaming the test would keep intent clear and avoid future confusion.

This issue also appears on line 147 of the same file.

        public async Task SerializeMultipleNonNullTypesAsV3OmitsType()

Copilot AI review requested due to automatic review settings August 4, 2026 07:52
This was referenced Nov 2, 2026
Paul Trampert (PaulTrampert) added a commit to PaulTrampert/PTrampert.SimplePatch that referenced this pull request Nov 6, 2026
Updated [Microsoft.AspNetCore.OpenApi](https://github.com/dotnet/dotnet)
from 10.0.12 to 10.0.14.

<details>
<summary>Release notes</summary>

_Sourced from [Microsoft.AspNetCore.OpenApi's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Updated
[Microsoft.CodeAnalysis.CSharp](https://github.com/dotnet/roslyn) from
4.14.0 to 5.9.0.

<details>
<summary>Release notes</summary>

_Sourced from [Microsoft.CodeAnalysis.CSharp's
releases](https://github.com/dotnet/roslyn/releases)._

## 5.0.4

[Release](https://github.com/dotnet/core/releases/tag/v5.0.4)

## 5.0.2

[Release
Notes](https://github.com/dotnet/core/blob/master/release-notes/5.0/5.0.2/5.0.2.md)
[Install
Instructions](https://github.com/dotnet/core/blob/master/release-notes/5.0/5.0.2/5.0.2-install-instructions.md)

# Repos

* [Core](https://github.com/dotnet/core/releases/tag/v5.0.2)

## 5.0.1

[Release
Notes](https://github.com/dotnet/core/blob/master/release-notes/5.0/5.0.1/5.0.1.md)
[Install
Instructions](https://github.com/dotnet/core/blob/master/release-notes/5.0/5.0.1/5.0.1-install-instructions.md)

# Repo

* [Core](https://github.com/dotnet/core/releases/tag/v5.0.1)

Commits viewable in [compare
view](https://github.com/dotnet/roslyn/commits).
</details>

Updated [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest)
from 18.10.1 to 18.11.0.

<details>
<summary>Release notes</summary>

_Sourced from [Microsoft.NET.Test.Sdk's
releases](https://github.com/microsoft/vstest/releases)._

## 18.11.0

<!-- Release notes generated using configuration in .github/release.yml
at rel/18.11 -->

## What's Changed
* Fix TRX logger mangling astral-plane (non-BMP) characters by
@​azat-msft in microsoft/vstest#16318
* Disable the MTP testhost by default by @​nohwnd in
microsoft/vstest#16337
* Fix OS-blind apphost probe in MTP bridge on Unix (regression from
#​16201) by @​azat-msft in
microsoft/vstest#16336
* Retarget the MTP client onto
Microsoft.Testing.Platform.ServerMode.Client.Sources by @​nohwnd in
microsoft/vstest#16300
* Pass arguments to PowerShell with -File instead of -command by
@​nohwnd in microsoft/vstest#16363
* Respect console logger verbosity from a settings file by @​nohwnd in
microsoft/vstest#16044
* Fix backslash normalization in VSTestCLIRunSettings on Unix by
@​nohwnd in microsoft/vstest#15795
* Docs: fix typo explicitely -> explicitly by @​vaibhav8a in
microsoft/vstest#16397
* Copy acceptance test diagnostic logs into the test results directory
by @​nohwnd in microsoft/vstest#16403

## New Contributors
* @​vaibhav8a made their first contribution in
microsoft/vstest#16397

**Full Changelog**:
microsoft/vstest@v18.10.1...v18.11.0

Commits viewable in [compare
view](microsoft/vstest@v18.10.1...v18.11.0).
</details>

Updated [Microsoft.OpenApi](https://github.com/Microsoft/OpenAPI.NET)
from 2.12.0 to 3.11.0.

<details>
<summary>Release notes</summary>

_Sourced from [Microsoft.OpenApi's
releases](https://github.com/Microsoft/OpenAPI.NET/releases)._

## 3.11.0

##
[3.11.0](microsoft/OpenAPI.NET@v3.10.2...v3.11.0)
(2026-10-19)


### Features

* **document:** add GetOperationById to search operations across path…
([#​3025](microsoft/OpenAPI.NET#3025))
([1dae1ff](microsoft/OpenAPI.NET@1dae1ff))


### Bug Fixes

* components-key validation timeouts under load
([#​3108](microsoft/OpenAPI.NET#3108))
([01d4729](microsoft/OpenAPI.NET@01d4729))
* **openapi:** omit null response descriptions
([afd4967](microsoft/OpenAPI.NET@afd4967))
* **serialization:** potential infinite loop when inlining references
([c6ef130](microsoft/OpenAPI.NET@c6ef130))
* **serialization:** references inlining
([#​3124](microsoft/OpenAPI.NET#3124))
([c6ef130](microsoft/OpenAPI.NET@c6ef130))

## 3.10.2

##
[3.10.2](microsoft/OpenAPI.NET@v3.10.1...v3.10.2)
(2026-08-20)


### Bug Fixes

* duplicate schema example when serializing to v2
([#​3045](microsoft/OpenAPI.NET#3045))
([50f5a2b](microsoft/OpenAPI.NET@50f5a2b))

## 3.10.1

##
[3.10.1](microsoft/OpenAPI.NET@v3.10.0...v3.10.1)
(2026-08-19)


### Bug Fixes

* circular ref guard
([#​3033](microsoft/OpenAPI.NET#3033))
([8018d40](microsoft/OpenAPI.NET@8018d40))
* harden yaml parsing
([#​3027](microsoft/OpenAPI.NET#3027))
([e0d5e9d](microsoft/OpenAPI.NET@e0d5e9d))

## 3.10.0

##
[3.10.0](microsoft/OpenAPI.NET@v3.9.0...v3.10.0)
(2026-08-11)


### Features

* adds deserialization of the example extension
([e5a1080](microsoft/OpenAPI.NET@e5a1080))
* do not ignore multiple types when serializing to 3.0
([#​2960](microsoft/OpenAPI.NET#2960))
([ebaf27a](microsoft/OpenAPI.NET@ebaf27a))
* serialize license identifier as extension for earlier versions
([d090989](microsoft/OpenAPI.NET@d090989))
* serialize license identifier as extension for earlier versions
([60971ba](microsoft/OpenAPI.NET@60971ba))


### Bug Fixes

* better nullability round-tripping
([655c2c8](microsoft/OpenAPI.NET@655c2c8))
* bound YAML anchor/alias expansion to prevent OOM (billion laughs)
([#​3000](microsoft/OpenAPI.NET#3000))
([2179326](microsoft/OpenAPI.NET@2179326))
* deserialize metadata url from extension in earlier version
([9387b01](microsoft/OpenAPI.NET@9387b01))
* marks deprecated properties from the specification as obsolete
([787b045](microsoft/OpenAPI.NET@787b045))
* marks deprecated properties from the specification as obsolete
([953c22a](microsoft/OpenAPI.NET@953c22a))
* **schema:** serialize compatibility examples from examples list
([5d8ec3a](microsoft/OpenAPI.NET@5d8ec3a))
* serialize examples as extension in v2/v3
([ff1dbc9](microsoft/OpenAPI.NET@ff1dbc9))
* serialize examples as extension in v2/v3
([edf3c67](microsoft/OpenAPI.NET@edf3c67))

## 3.9.0

##
[3.9.0](microsoft/OpenAPI.NET@v3.8.0...v3.9.0)
(2026-07-15)


### Features

* adds support for anchor and id external resolution
([1591007](microsoft/OpenAPI.NET@1591007))
* **schema:** resolve bare $dynamicRef via $dynamicAnchor index
([#​2913](microsoft/OpenAPI.NET#2913))
([eacc2fc](microsoft/OpenAPI.NET@eacc2fc))
* support relative URI resolution in $dynamicRef
([#​2928](microsoft/OpenAPI.NET#2928))
([#​2945](microsoft/OpenAPI.NET#2945))
([821053b](microsoft/OpenAPI.NET@821053b))


### Bug Fixes

* adds explicit error message for invalid json pointers
([63fc55d](microsoft/OpenAPI.NET@63fc55d))
* adds explicit error message for invalid json pointers
([bc93efe](microsoft/OpenAPI.NET@bc93efe))
* default mapping is not being serialized with the correct shape
([fe4a25f](microsoft/OpenAPI.NET@fe4a25f))
* differentiate unset value from null value in OpenApiSchema.Const
([#​2936](microsoft/OpenAPI.NET#2936))
([07b525f](microsoft/OpenAPI.NET@07b525f))
* handle nullability more accurately during serialization for 3.0/2.0
([#​2933](microsoft/OpenAPI.NET#2933))
([0ace243](microsoft/OpenAPI.NET@0ace243))
* validate required properties of security scheme before serialization
([#​2952](microsoft/OpenAPI.NET#2952))
([f31b192](microsoft/OpenAPI.NET@f31b192))

## 3.8.0

##
[3.8.0](microsoft/OpenAPI.NET@v3.7.0...v3.8.0)
(2026-07-03)


### Features

* add JsonConverter for OpenApiSchema System.Text.Json serialization
([#​2915](microsoft/OpenAPI.NET#2915))
([2f8b3d2](microsoft/OpenAPI.NET@2f8b3d2))
* **library:** support schema keywords on references
([434b2f8](microsoft/OpenAPI.NET@434b2f8))
* **library:** support schema keywords on references
([66a9d04](microsoft/OpenAPI.NET@66a9d04)),
closes [#​2903](microsoft/OpenAPI.NET#2903)


### Bug Fixes

* Don't silently skip null assignment to OpenApiDocument.Tags
([3764142](microsoft/OpenAPI.NET@3764142))
* handling of nullable enums for 3.0
([#​2920](microsoft/OpenAPI.NET#2920))
([beb68f5](microsoft/OpenAPI.NET@beb68f5))
* **library:** keep v3 schema references ref-only
([c938727](microsoft/OpenAPI.NET@c938727))
* preserve JSON Schema 2020-12 keyword siblings on $ref schemas for OAS
3.1+ ([#​2896](microsoft/OpenAPI.NET#2896))
([08160c8](microsoft/OpenAPI.NET@08160c8))
* use async method for crypto flush
([6e675d9](microsoft/OpenAPI.NET@6e675d9))

## 3.7.0

##
[3.7.0](microsoft/OpenAPI.NET@v3.6.0...v3.7.0)
(2026-06-10)


### Features

* add contains/minContains/maxContains members
([78475e3](microsoft/OpenAPI.NET@78475e3))
* add contains/minContains/maxContains members
([1a974f8](microsoft/OpenAPI.NET@1a974f8))
* **library:** add missing json schema properties
([9b1aed6](microsoft/OpenAPI.NET@9b1aed6))
* **library:** add missing json schema properties
([82f84e0](microsoft/OpenAPI.NET@82f84e0))


### Bug Fixes

* **library:** always copy unevaluated properties
([4907d1c](microsoft/OpenAPI.NET@4907d1c))
* **library:** avoid false circular refs for external schema re-exports
([b635242](microsoft/OpenAPI.NET@b635242))
* **library:** avoid false circular refs for external schema re-exports
([7a443c2](microsoft/OpenAPI.NET@7a443c2))
* **library:** remove unshipped schema extension fallback
([cf54bb3](microsoft/OpenAPI.NET@cf54bb3))
* **library:** use version-specific schema keyword callbacks
([6e22ec6](microsoft/OpenAPI.NET@6e22ec6))
* **library:** use x-jsonschema schema extensions
([eb1891a](microsoft/OpenAPI.NET@eb1891a))

## 3.6.0

##
[3.6.0](microsoft/OpenAPI.NET@v3.5.5...v3.6.0)
(2026-06-01)


### Features

* **reader:** remove ParseNode infrastructure
([9b4f45b](microsoft/OpenAPI.NET@9b4f45b))
* Significant performance improvements resulting ~40% reduced
allocations when parsing JSON descriptions, ~25% for YAML.

## 3.5.5

##
[3.5.5](microsoft/OpenAPI.NET@v3.5.4...v3.5.5)
(2026-05-28)


### Bug Fixes

* **reader:** preserve Null flag when nullable appears before type in
V3.0/V3.1/V3.2 deserializers
([2b9d7f4](microsoft/OpenAPI.NET@2b9d7f4))

## 3.5.4

##
[3.5.4](microsoft/OpenAPI.NET@v3.5.3...v3.5.4)
(2026-05-26)


### Bug Fixes

* **library:** handle circular schema references
([b3cd42b](microsoft/OpenAPI.NET@b3cd42b))
* **library:** handle circular schema references
([91a989f](microsoft/OpenAPI.NET@91a989f))

## 3.5.3

##
[3.5.3](microsoft/OpenAPI.NET@v3.5.2...v3.5.3)
(2026-04-27)


### Bug Fixes

* null reference exception for boolean component schemas
([f97f91a](microsoft/OpenAPI.NET@f97f91a))
* null reference exception for boolean component schemas
([fe0b50a](microsoft/OpenAPI.NET@fe0b50a))
* **schema:** support boolean schemas in deserializer for OpenAPI
3.1/3.2
([05b44be](microsoft/OpenAPI.NET@05b44be))


### Performance Improvements

* **schema:** optimize boolean schema deserialization
([7316e3f](microsoft/OpenAPI.NET@7316e3f))

## 3.5.2

##
[3.5.2](microsoft/OpenAPI.NET@v3.5.1...v3.5.2)
(2026-04-14)


### Bug Fixes

* **hidi:** update Microsoft.OpenApi.OData to 3.2.1
([b0a68fb](microsoft/OpenAPI.NET@b0a68fb))
* **hidi:** update Microsoft.OpenApi.OData to 3.2.1
([8c22ab2](microsoft/OpenAPI.NET@8c22ab2)),
closes [#​2811](microsoft/OpenAPI.NET#2811)

## 3.5.1

##
[3.5.1](microsoft/OpenAPI.NET@v3.5.0...v3.5.1)
(2026-03-31)


### Bug Fixes

* security scheme references serialization
([a5acb89](microsoft/OpenAPI.NET@a5acb89))

## 3.5.0

##
[3.5.0](microsoft/OpenAPI.NET@v3.4.0...v3.5.0)
(2026-03-20)


### Features

* **library:** add Extensions support for schema references in
v3.1/v3.2; add SerializeAsV32 with loop detection
([9b422bf](microsoft/OpenAPI.NET@9b422bf))


### Bug Fixes

* a bug where path parameter validation would fail if they contained
forbidden JSON pointer characters
([ef55b2c](microsoft/OpenAPI.NET@ef55b2c))
* a bug where path parameter validation would fail if they contained
forbidden JSON pointer characters
([4b3164a](microsoft/OpenAPI.NET@4b3164a))
* double encoding of json pointer for invalid reference rule
([b246cd0](microsoft/OpenAPI.NET@b246cd0))
* encoding of special characters for JSON paths
([4c757e1](microsoft/OpenAPI.NET@4c757e1))
* **library:** do not emit unevaluatedProperties for non-object schemas
([852fb4c](microsoft/OpenAPI.NET@852fb4c))
* **library:** do not emit unevaluatedProperties for non-object schemas
([19538aa](microsoft/OpenAPI.NET@19538aa))
* **library:** enforce spec-compliant $ref serialization; add Extensions
support for schema references in v3.1/v3.2
([9bf61de](microsoft/OpenAPI.NET@9bf61de))
* potential double encoding of paths
([471a61a](microsoft/OpenAPI.NET@471a61a))

## 3.4.0

##
[3.4.0](microsoft/OpenAPI.NET@v3.3.1...v3.4.0)
(2026-03-04)


### Features

* **library:** preserve PatternProperties as
x-jsonschema-patternProperties extension for OpenAPI v2/v3.0
serialization
([d969fdc](microsoft/OpenAPI.NET@d969fdc))
* **library:** Preserve PatternProperties via
x-jsonschema-patternProperties extension for OpenAPI v2/v3.0
([16ab5e4](microsoft/OpenAPI.NET@16ab5e4))
* **securityscheme:** add oauth2MetadataUrl support (OpenAPI 3.2)
([4509488](microsoft/OpenAPI.NET@4509488))


### Bug Fixes

* implement unevaluatedProperties as schema per JSON Schema 2020-12
([#​2728](microsoft/OpenAPI.NET#2728))
([7c13fb3](microsoft/OpenAPI.NET@7c13fb3))
* **library:** serialize additionalProperties schema in OpenAPI V2
([f3165fa](microsoft/OpenAPI.NET@f3165fa))
* **library:** serialize additionalProperties schema in OpenAPI V2
documents
([3d07756](microsoft/OpenAPI.NET@3d07756))
* optimize parsing V3.1 documents by reducing GetLocation method
allocation on hot
path([#​2748](microsoft/OpenAPI.NET#2748))
([f690681](microsoft/OpenAPI.NET@f690681))

## 3.3.1

##
[3.3.1](microsoft/OpenAPI.NET@v3.3.0...v3.3.1)
(2026-01-22)


### Features

* **models:** add shared Content interface
([#​2695](microsoft/OpenAPI.NET#2695))
([338566f](microsoft/OpenAPI.NET@338566f))


### Bug Fixes

* broken binary compatibility due to interface changes in previous
version
([d96bba7](microsoft/OpenAPI.NET@d96bba7))

## 3.3.0

##
[3.3.0](microsoft/OpenAPI.NET@v3.2.0...v3.3.0)
(2026-01-21)


### Features

* **models:** add shared Content interface
([9e13b25](microsoft/OpenAPI.NET@9e13b25))
* **models:** add shared Content interface
([#​2695](microsoft/OpenAPI.NET#2695))
([9e13b25](microsoft/OpenAPI.NET@9e13b25))
* **models:** support mutualTLS security scheme
([a4efdfe](microsoft/OpenAPI.NET@a4efdfe))

## 3.2.0

##
[3.2.0](microsoft/OpenAPI.NET@v3.1.3...v3.2.0)
(2026-01-19)


### Features

* hidi validate command now logs warnings
([76a3c0f](microsoft/OpenAPI.NET@76a3c0f))
* hidi validate command now logs warnings
([62e7d56](microsoft/OpenAPI.NET@62e7d56))


### Bug Fixes

* discriminator property validation fails any/allOf cases when it
shouldn't
([fb6cecc](microsoft/OpenAPI.NET@fb6cecc))
* discriminator property validation fails any/allOf cases when it
shouldn't
([a8fb81c](microsoft/OpenAPI.NET@a8fb81c))

## 3.1.3

##
[3.1.3](microsoft/OpenAPI.NET@v3.1.2...v3.1.3)
(2026-01-16)


### Bug Fixes

* Support custom tag ordering
([008576c](microsoft/OpenAPI.NET@008576c))
* Support custom tag ordering
([7610d07](microsoft/OpenAPI.NET@7610d07))

## 3.1.2

##
[3.1.2](microsoft/OpenAPI.NET@v3.1.1...v3.1.2)
(2026-01-06)


### Bug Fixes

* correct error pointer when extension parser throws OpenApiException
([43c75a9](microsoft/OpenAPI.NET@43c75a9))
* wrap extension parser calls in try-catch to ensure correct error
pointers
([50b44aa](microsoft/OpenAPI.NET@50b44aa))

## 3.1.1

##
[3.1.1](microsoft/OpenAPI.NET@v3.1.0...v3.1.1)
(2025-12-18)


### Bug Fixes

* **schema:** always serialize `additionalProperties: false`
([6651c36](microsoft/OpenAPI.NET@6651c36))
* **schema:** always serialize `additionalProperties: false`
([e36fc95](microsoft/OpenAPI.NET@e36fc95))

## 3.1.0

##
[3.1.0](microsoft/OpenAPI.NET@v3.0.3...v3.1.0)
(2025-12-17)


### Features

* Add `type: "null"` downcasting when in oneOf and anyOf for OpenAPI v3
([782cf8d](microsoft/OpenAPI.NET@782cf8d))

## 3.0.3

##
[3.0.3](microsoft/OpenAPI.NET@v3.0.2...v3.0.3)
(2025-12-16)


### Bug Fixes

* load JSON documents that are preceded by multiple whitespace
([6461bac](microsoft/OpenAPI.NET@6461bac))
* non-seekable json streams would fail to load as a document
([2436d73](microsoft/OpenAPI.NET@2436d73))
* reading streams in an asp.net context would cause async exceptions
([f9e5248](microsoft/OpenAPI.NET@f9e5248))

## 3.0.2

##
[3.0.2](microsoft/OpenAPI.NET@v3.0.1...v3.0.2)
(2025-12-08)


### Bug Fixes

* additional properties serialization should not emit a schema in v2
([946cba9](microsoft/OpenAPI.NET@946cba9))
* additional properties serialization should not emit booleans in v3.1+
([946cba9](microsoft/OpenAPI.NET@946cba9))

## 3.0.1

##
[3.0.1](microsoft/OpenAPI.NET@v3.0.0...v3.0.1)
(2025-11-17)


### Bug Fixes

* empty strings should be quoted in yaml
([8d215f9](microsoft/OpenAPI.NET@8d215f9))
* empty strings should be quoted in yaml
([0ca10db](microsoft/OpenAPI.NET@0ca10db))

## 3.0.0

##
[3.0.0](microsoft/OpenAPI.NET@v2.3.9...v3.0.0)
(2025-11-11)


### ⚠ BREAKING CHANGES

* adds support for OpenAPI 3.2.0

> Note: Please refer to the [upgrade
guide](https://github.com/microsoft/OpenAPI.NET/blob/main/docs/upgrade-guide-3.md)
for a detailed description of the breaking changes.

> Note: ASP.net users should remain on version 1.X for ASP.net < 10, and
version 2.X for ASP.net 10, this new major version will be implemented
in a future version of ASP.net, [more
information](https://github.com/microsoft/OpenAPI.NET/blob/main/CONTRIBUTING.md#branches-and-support-policy)

### Features

* adds support for OpenAPI 3.2.0
([765a8dd](microsoft/OpenAPI.NET@765a8dd))

### Special thanks

- [Matthieu Costabello](https://github.com/kilifu)

## 2.13.0

##
[2.13.0](microsoft/OpenAPI.NET@v2.12.2...v2.13.0)
(2026-10-19)


### Features

* **document:** add GetOperationById to search operations across path…
([#​3025](microsoft/OpenAPI.NET#3025))
([#​3074](microsoft/OpenAPI.NET#3074))
([75d6cea](microsoft/OpenAPI.NET@75d6cea))


### Bug Fixes

* components-key validation timeouts under load
([#​3108](microsoft/OpenAPI.NET#3108))
([#​3112](microsoft/OpenAPI.NET#3112))
([5369417](microsoft/OpenAPI.NET@5369417))
* **openapi:** omit null response descriptions
([1344a43](microsoft/OpenAPI.NET@1344a43))

## 2.12.2

##
[2.12.2](microsoft/OpenAPI.NET@v2.12.1...v2.12.2)
(2026-08-20)


### Bug Fixes

* duplicate schema example when serializing to v2
([#​3046](microsoft/OpenAPI.NET#3046))
([a6366be](microsoft/OpenAPI.NET@a6366be))

## 2.12.1

##
[2.12.1](microsoft/OpenAPI.NET@v2.12.0...v2.12.1)
(2026-08-19)


### Bug Fixes

* circular ref guard
([#​3033](microsoft/OpenAPI.NET#3033))
([#​3039](microsoft/OpenAPI.NET#3039))
([406e6fd](microsoft/OpenAPI.NET@406e6fd))
* harden yaml parsing
([#​3034](microsoft/OpenAPI.NET#3034))
([fdc5718](microsoft/OpenAPI.NET@fdc5718))

Commits viewable in [compare
view](microsoft/OpenAPI.NET@v2.12.0...v3.11.0).
</details>

Updated [NUnit3TestAdapter](https://github.com/nunit/nunit3-vs-adapter)
from 6.3.0 to 6.3.1.

<details>
<summary>Release notes</summary>

_Sourced from [NUnit3TestAdapter's
releases](https://github.com/nunit/nunit3-vs-adapter/releases)._

## 6.3.1

This is a hotfix release for issue
[1504](nunit/nunit3-vs-adapter#1504)

Commits viewable in [compare
view](nunit/nunit3-vs-adapter@V6.3.0...V6.3.1).
</details>

Updated
[Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore)
from 10.2.3 to 10.3.1.

<details>
<summary>Release notes</summary>

_Sourced from [Swashbuckle.AspNetCore's
releases](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/releases)._

## 10.3.1

## What's Changed

* Remove Swashbuckle.AspNetCore.ApiTesting.Xunit by @​martincostello in
domaindrivendev/Swashbuckle.AspNetCore#4188
* Migrate to xunit v3 by @​martincostello in
domaindrivendev/Swashbuckle.AspNetCore#4189
* Normalize line endings by @​martincostello in
domaindrivendev/Swashbuckle.AspNetCore#4190
* Update .git-blame-ignore-revs by @​martincostello in
domaindrivendev/Swashbuckle.AspNetCore#4191
* Fix `AmbiguousMatchException` for `[FromQuery]` by @​SENESO in
domaindrivendev/Swashbuckle.AspNetCore#4209
* Avoid deadlock when a schema filter depends on
`ISerializerDataContractResolver` by @​DevKaurav-14 in
domaindrivendev/Swashbuckle.AspNetCore#4210
* Fix tests by @​martincostello in
domaindrivendev/Swashbuckle.AspNetCore#4214

## Deprecations

> [!IMPORTANT]
> Swashbuckle.AspNetCore.ApiTesting.Xunit depended on Xunit v2, which is
no longer supported.
>
> The package has been removed and no further versions will be released.

## New Contributors

* @​SENESO made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#4209
* @​DevKaurav-14 made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#4210

**Full Changelog**:
domaindrivendev/Swashbuckle.AspNetCore@v10.3.0...v10.3.1


## 10.3.0

## What's Changed

* Change nullability handling for schemas with `anyOf`, `allOf`, `oneOf`
or `type = null` by @​ldeluigi in
domaindrivendev/Swashbuckle.AspNetCore#3976
* Handle leading slash on route prefix during index.html GET by
@​superstator in
domaindrivendev/Swashbuckle.AspNetCore#4084
* Move NRT handling to DataContractResolver by @​desjoerd in
domaindrivendev/Swashbuckle.AspNetCore#3998
* Clarify nullable behaviour by @​martincostello in
domaindrivendev/Swashbuckle.AspNetCore#4094
* Fix review issues for caching and encoding by @​martincostello in
domaindrivendev/Swashbuckle.AspNetCore#4093
* Support multiple response types per status code by @​DeagleGross in
domaindrivendev/Swashbuckle.AspNetCore#4100
* Add coverage for `AddServer` across multiple documents by
@​RaphaelFakhri in
domaindrivendev/Swashbuckle.AspNetCore#4115
* Fix Swagger sort key fallback for empty endpoint tags metadata by
@​AleksaMCode in
domaindrivendev/Swashbuckle.AspNetCore#4125
* Fix parameter matching to consider location when names collide by
@​nonsoikem in
domaindrivendev/Swashbuckle.AspNetCore#4126
* Emit form encoding for properties of a complex form parameter by
@​RaphaelFakhri in
domaindrivendev/Swashbuckle.AspNetCore#4128
* Keep a property's own summary when comments come from several XML
files by @​RaphaelFakhri in
domaindrivendev/Swashbuckle.AspNetCore#4129
* Strip query string from relative document URLs in Swagger UI by
@​GabeSilvaDev in
domaindrivendev/Swashbuckle.AspNetCore#4152
* Document that System.Text.Json ignores `[EnumMember]` by
@​RaphaelFakhri in
domaindrivendev/Swashbuckle.AspNetCore#4127
* Drop the regex route constraint from the default Swagger route by
@​RaphaelFakhri in
domaindrivendev/Swashbuckle.AspNetCore#4130
* Serialize custom values in the UI `ConfigObject.AdditionalItems` by
@​RaphaelFakhri in
domaindrivendev/Swashbuckle.AspNetCore#4132
* Use Minimal APIs JSON options when MVC is not registered by
@​RaphaelFakhri in
domaindrivendev/Swashbuckle.AspNetCore#4116
* Resolve enum contracts against the underlying type under source
generation by @​RaphaelFakhri in
domaindrivendev/Swashbuckle.AspNetCore#4131

## New Contributors

* @​ldeluigi made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#3976
* @​superstator made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#4084
* @​desjoerd made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#3998
* @​RaphaelFakhri made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#4115
* @​AleksaMCode made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#4125
* @​nonsoikem made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#4126
* @​GabeSilvaDev made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#4152
* @​JulianThoms made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#4182

**Full Changelog**:
domaindrivendev/Swashbuckle.AspNetCore@v10.2.3...v10.3.0


Commits viewable in [compare
view](domaindrivendev/Swashbuckle.AspNetCore@v10.2.3...v10.3.1).
</details>

Updated
[Swashbuckle.AspNetCore.SwaggerGen](https://github.com/domaindrivendev/Swashbuckle.AspNetCore)
from 10.2.3 to 10.3.1.

<details>
<summary>Release notes</summary>

_Sourced from [Swashbuckle.AspNetCore.SwaggerGen's
releases](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/releases)._

## 10.3.1

## What's Changed

* Remove Swashbuckle.AspNetCore.ApiTesting.Xunit by @​martincostello in
domaindrivendev/Swashbuckle.AspNetCore#4188
* Migrate to xunit v3 by @​martincostello in
domaindrivendev/Swashbuckle.AspNetCore#4189
* Normalize line endings by @​martincostello in
domaindrivendev/Swashbuckle.AspNetCore#4190
* Update .git-blame-ignore-revs by @​martincostello in
domaindrivendev/Swashbuckle.AspNetCore#4191
* Fix `AmbiguousMatchException` for `[FromQuery]` by @​SENESO in
domaindrivendev/Swashbuckle.AspNetCore#4209
* Avoid deadlock when a schema filter depends on
`ISerializerDataContractResolver` by @​DevKaurav-14 in
domaindrivendev/Swashbuckle.AspNetCore#4210
* Fix tests by @​martincostello in
domaindrivendev/Swashbuckle.AspNetCore#4214

## Deprecations

> [!IMPORTANT]
> Swashbuckle.AspNetCore.ApiTesting.Xunit depended on Xunit v2, which is
no longer supported.
>
> The package has been removed and no further versions will be released.

## New Contributors

* @​SENESO made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#4209
* @​DevKaurav-14 made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#4210

**Full Changelog**:
domaindrivendev/Swashbuckle.AspNetCore@v10.3.0...v10.3.1


## 10.3.0

## What's Changed

* Change nullability handling for schemas with `anyOf`, `allOf`, `oneOf`
or `type = null` by @​ldeluigi in
domaindrivendev/Swashbuckle.AspNetCore#3976
* Handle leading slash on route prefix during index.html GET by
@​superstator in
domaindrivendev/Swashbuckle.AspNetCore#4084
* Move NRT handling to DataContractResolver by @​desjoerd in
domaindrivendev/Swashbuckle.AspNetCore#3998
* Clarify nullable behaviour by @​martincostello in
domaindrivendev/Swashbuckle.AspNetCore#4094
* Fix review issues for caching and encoding by @​martincostello in
domaindrivendev/Swashbuckle.AspNetCore#4093
* Support multiple response types per status code by @​DeagleGross in
domaindrivendev/Swashbuckle.AspNetCore#4100
* Add coverage for `AddServer` across multiple documents by
@​RaphaelFakhri in
domaindrivendev/Swashbuckle.AspNetCore#4115
* Fix Swagger sort key fallback for empty endpoint tags metadata by
@​AleksaMCode in
domaindrivendev/Swashbuckle.AspNetCore#4125
* Fix parameter matching to consider location when names collide by
@​nonsoikem in
domaindrivendev/Swashbuckle.AspNetCore#4126
* Emit form encoding for properties of a complex form parameter by
@​RaphaelFakhri in
domaindrivendev/Swashbuckle.AspNetCore#4128
* Keep a property's own summary when comments come from several XML
files by @​RaphaelFakhri in
domaindrivendev/Swashbuckle.AspNetCore#4129
* Strip query string from relative document URLs in Swagger UI by
@​GabeSilvaDev in
domaindrivendev/Swashbuckle.AspNetCore#4152
* Document that System.Text.Json ignores `[EnumMember]` by
@​RaphaelFakhri in
domaindrivendev/Swashbuckle.AspNetCore#4127
* Drop the regex route constraint from the default Swagger route by
@​RaphaelFakhri in
domaindrivendev/Swashbuckle.AspNetCore#4130
* Serialize custom values in the UI `ConfigObject.AdditionalItems` by
@​RaphaelFakhri in
domaindrivendev/Swashbuckle.AspNetCore#4132
* Use Minimal APIs JSON options when MVC is not registered by
@​RaphaelFakhri in
domaindrivendev/Swashbuckle.AspNetCore#4116
* Resolve enum contracts against the underlying type under source
generation by @​RaphaelFakhri in
domaindrivendev/Swashbuckle.AspNetCore#4131

## New Contributors

* @​ldeluigi made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#3976
* @​superstator made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#4084
* @​desjoerd made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#3998
* @​RaphaelFakhri made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#4115
* @​AleksaMCode made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#4125
* @​nonsoikem made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#4126
* @​GabeSilvaDev made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#4152
* @​JulianThoms made their first contribution in
domaindrivendev/Swashbuckle.AspNetCore#4182

**Full Changelog**:
domaindrivendev/Swashbuckle.AspNetCore@v10.2.3...v10.3.0


Commits viewable in [compare
view](domaindrivendev/Swashbuckle.AspNetCore@v10.2.3...v10.3.1).
</details>

Updated [System.CodeDom](https://github.com/dotnet/dotnet) from 10.0.12
to 10.0.14.

<details>
<summary>Release notes</summary>

_Sourced from [System.CodeDom's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Paul Trampert <paul.trampert@ptrampert.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Paul Trampert <5550942+PaulTrampert@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consider representing multiple types in 3.0 using anyOf or oneOf

5 participants