From e38e511de5c90a4e73868cb292a2fff7cd7071a4 Mon Sep 17 00:00:00 2001 From: Steven Yeh Date: Fri, 16 Jan 2026 19:32:14 -0600 Subject: [PATCH 1/7] Fix Typo in IOpenApiReadOnlyExtensible.cs --- src/Microsoft.OpenApi/Interfaces/IOpenApiReadOnlyExtensible.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi/Interfaces/IOpenApiReadOnlyExtensible.cs b/src/Microsoft.OpenApi/Interfaces/IOpenApiReadOnlyExtensible.cs index fac742d7d..c059842c0 100644 --- a/src/Microsoft.OpenApi/Interfaces/IOpenApiReadOnlyExtensible.cs +++ b/src/Microsoft.OpenApi/Interfaces/IOpenApiReadOnlyExtensible.cs @@ -3,7 +3,7 @@ namespace Microsoft.OpenApi; /// -/// Represents an Extensible Open API element elements can be rad from. +/// Represents an Extensible Open API element elements can be read from. /// public interface IOpenApiReadOnlyExtensible { From 7def73d774d1f0e96118e92b636e52cbea371f2d Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 19 Jan 2026 11:15:25 -0500 Subject: [PATCH 2/7] fix: discriminator property validation fails any/allOf cases when it shouldn't Signed-off-by: Vincent Biret --- .../Validations/Rules/OpenApiSchemaRules.cs | 41 ++++---- .../PublicApi/PublicApi.approved.txt | 4 + .../OpenApiSchemaValidationTests.cs | 99 ++++++++++++++++++- 3 files changed, 126 insertions(+), 18 deletions(-) diff --git a/src/Microsoft.OpenApi/Validations/Rules/OpenApiSchemaRules.cs b/src/Microsoft.OpenApi/Validations/Rules/OpenApiSchemaRules.cs index 70d558a13..4f2a122a9 100644 --- a/src/Microsoft.OpenApi/Validations/Rules/OpenApiSchemaRules.cs +++ b/src/Microsoft.OpenApi/Validations/Rules/OpenApiSchemaRules.cs @@ -5,6 +5,8 @@ namespace Microsoft.OpenApi { + using System; + using System.ComponentModel; using System.Linq; /// @@ -48,6 +50,7 @@ public static class OpenApiSchemaRules { var discriminatorName = schema.Discriminator?.PropertyName; +#pragma warning disable CS0618 // Type or member is obsolete if (!ValidateChildSchemaAgainstDiscriminator(schema, discriminatorName)) { context.Enter("discriminator"); @@ -56,6 +59,7 @@ public static class OpenApiSchemaRules schema is OpenApiSchemaReference { Reference: not null} schemaReference ? schemaReference.Reference.Id : string.Empty, discriminatorName)); context.Exit(); } +#pragma warning restore CS0618 // Type or member is obsolete } }); @@ -65,6 +69,8 @@ public static class OpenApiSchemaRules /// The parent schema. /// Adds support for polymorphism. The discriminator is an object name that is used to differentiate /// between other schemas which may satisfy the payload description. + [Obsolete("This method will be made private in future versions.")] + [Browsable(false)] public static bool ValidateChildSchemaAgainstDiscriminator(IOpenApiSchema schema, string? discriminatorName) { if (discriminatorName is not null) @@ -72,15 +78,15 @@ public static bool ValidateChildSchemaAgainstDiscriminator(IOpenApiSchema schema if (schema.Required is null || !schema.Required.Contains(discriminatorName)) { // recursively check nested schema.OneOf, schema.AnyOf or schema.AllOf and their required fields for the discriminator - if (schema.OneOf?.Count != 0) + if (schema.OneOf is { Count: > 0}) { return TraverseSchemaElements(discriminatorName, schema.OneOf); } - if (schema.AnyOf?.Count != 0) + if (schema.AnyOf is { Count: > 0}) { return TraverseSchemaElements(discriminatorName, schema.AnyOf); } - if (schema.AllOf?.Count != 0) + if (schema.AllOf is { Count: > 0}) { return TraverseSchemaElements(discriminatorName, schema.AllOf); } @@ -102,25 +108,26 @@ public static bool ValidateChildSchemaAgainstDiscriminator(IOpenApiSchema schema /// between other schemas which may satisfy the payload description. /// The child schema. /// + [Obsolete("This method will be made private in future versions.")] + [Browsable(false)] public static bool TraverseSchemaElements(string discriminatorName, IList? childSchema) { - if (childSchema is not null) + if (childSchema is null) { - foreach (var childItem in childSchema) + return false; + } + foreach (var childItem in childSchema) + { + if ((!childItem.Properties?.ContainsKey(discriminatorName) ?? false) && + (!childItem.Required?.Contains(discriminatorName) ?? false)) { - if ((!childItem.Properties?.ContainsKey(discriminatorName) ?? false) && - (!childItem.Required?.Contains(discriminatorName) ?? false)) - { - return ValidateChildSchemaAgainstDiscriminator(childItem, discriminatorName); - } - else - { - return true; - } + return ValidateChildSchemaAgainstDiscriminator(childItem, discriminatorName); } - return false; - } - + else + { + return true; + } + } return false; } } diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index 39cfb8ccc..d0b8989ef 100644 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -1261,7 +1261,11 @@ namespace Microsoft.OpenApi { public static Microsoft.OpenApi.ValidationRule ValidateSchemaDiscriminator { get; } public static Microsoft.OpenApi.ValidationRule ValidateSchemaPropertyHasValue { get; } + [System.ComponentModel.Browsable(false)] + [System.Obsolete("This method will be made private in future versions.")] public static bool TraverseSchemaElements(string discriminatorName, System.Collections.Generic.IList? childSchema) { } + [System.ComponentModel.Browsable(false)] + [System.Obsolete("This method will be made private in future versions.")] public static bool ValidateChildSchemaAgainstDiscriminator(Microsoft.OpenApi.IOpenApiSchema schema, string? discriminatorName) { } } public class OpenApiSecurityRequirement : System.Collections.Generic.Dictionary>, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiSerializable diff --git a/test/Microsoft.OpenApi.Tests/Validations/OpenApiSchemaValidationTests.cs b/test/Microsoft.OpenApi.Tests/Validations/OpenApiSchemaValidationTests.cs index f22806825..fdf36e0b4 100644 --- a/test/Microsoft.OpenApi.Tests/Validations/OpenApiSchemaValidationTests.cs +++ b/test/Microsoft.OpenApi.Tests/Validations/OpenApiSchemaValidationTests.cs @@ -246,7 +246,7 @@ public void ValidateSchemaRequiredFieldListMustContainThePropertySpecifiedInTheD } [Fact] - public void ValidateOneOfSchemaPropertyNameContainsPropertySpecifiedInTheDiscriminator() + public void ValidateOneOfSchemaPropertyNameContainsPropertySpecifiedInTheDiscriminatorOneOf() { // Arrange var components = new OpenApiComponents @@ -293,5 +293,102 @@ public void ValidateOneOfSchemaPropertyNameContainsPropertySpecifiedInTheDiscrim //Assert Assert.Empty(errors); } + + [Fact] + public void ValidateOneOfSchemaPropertyNameContainsPropertySpecifiedInTheDiscriminatorAnyOf() + { + // Arrange + var components = new OpenApiComponents + { + Schemas = new Dictionary + { + { + "Person", + new OpenApiSchema + { + Type = JsonSchemaType.Array, + Discriminator = new() + { + PropertyName = "type" + }, + AnyOf = + [ + new OpenApiSchema() + { + Properties = new Dictionary + { + { + "type", + new OpenApiSchema + { + Type = JsonSchemaType.Array + } + } + }, + } + ], + } + } + } + }; + + // Act + var validator = new OpenApiValidator(ValidationRuleSet.GetDefaultRuleSet()); + var walker = new OpenApiWalker(validator); + walker.Walk(components); + + var errors = validator.Errors; + + //Assert + Assert.Empty(errors); + } + [Fact] + public void ValidateOneOfSchemaPropertyNameContainsPropertySpecifiedInTheDiscriminatorAllOf() + { + // Arrange + var components = new OpenApiComponents + { + Schemas = new Dictionary + { + { + "Person", + new OpenApiSchema + { + Type = JsonSchemaType.Array, + Discriminator = new() + { + PropertyName = "type" + }, + AllOf = + [ + new OpenApiSchema() + { + Properties = new Dictionary + { + { + "type", + new OpenApiSchema + { + Type = JsonSchemaType.Array + } + } + }, + } + ], + } + } + } + }; + + // Act + var validator = new OpenApiValidator(ValidationRuleSet.GetDefaultRuleSet()); + var walker = new OpenApiWalker(validator); + walker.Walk(components); + + var errors = validator.Errors; + + //Assert + Assert.Empty(errors); + } } } From 18ed5acce9661639e1698f19c194e520eb5c93c1 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 19 Jan 2026 13:13:05 -0500 Subject: [PATCH 3/7] feat: hidi validate command now logs warnings Signed-off-by: Vincent Biret --- src/Microsoft.OpenApi.Hidi/OpenApiService.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.OpenApi.Hidi/OpenApiService.cs b/src/Microsoft.OpenApi.Hidi/OpenApiService.cs index 797ec2359..b35cc2cbb 100644 --- a/src/Microsoft.OpenApi.Hidi/OpenApiService.cs +++ b/src/Microsoft.OpenApi.Hidi/OpenApiService.cs @@ -398,6 +398,7 @@ private static async Task ParseOpenApiAsync(string openApiFile, bool logger.LogTrace("{Timestamp}ms: Completed parsing.", stopwatch.ElapsedMilliseconds); LogErrors(logger, result); + LogWarnings(logger, result); stopwatch.Stop(); } @@ -652,7 +653,7 @@ private static string GetInputPathExtension(string? openapi = null, string? csdl private static void LogErrors(ILogger logger, ReadResult result) { var context = result.Diagnostic; - if (context is not null && context.Errors.Count != 0) + if (context is { Errors.Count: > 0 }) { using (logger.BeginScope("Detected errors")) { @@ -664,6 +665,21 @@ private static void LogErrors(ILogger logger, ReadResult result) } } + private static void LogWarnings(ILogger logger, ReadResult result) + { + var context = result.Diagnostic; + if (context is { Warnings.Count: > 0 }) + { + using (logger.BeginScope("Detected warnings")) + { + foreach (var warning in context.Warnings) + { + logger.LogWarning("Detected warning during parsing: {Warning}", warning.ToString()); + } + } + } + } + internal static void WriteTreeDocumentAsMarkdown(string openapiUrl, OpenApiDocument document, StreamWriter writer) { var rootNode = OpenApiUrlTreeNode.Create(document, "main"); From f09ce7915b3a43d18b68a9d155d2a838a71833fc Mon Sep 17 00:00:00 2001 From: "release-please-token-provider[bot]" <225477224+release-please-token-provider[bot]@users.noreply.github.com> Date: Mon, 19 Jan 2026 18:59:57 +0000 Subject: [PATCH 4/7] chore(support/v2): release 2.5.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 14 ++++++++++++++ Directory.Build.props | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 2b7962cdd..4dedeaebc 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.4.3" + ".": "2.5.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 457ff02e5..3098a8f17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## [2.5.0](https://github.com/microsoft/OpenAPI.NET/compare/v2.4.3...v2.5.0) (2026-01-19) + + +### Features + +* hidi validate command now logs warnings ([1d3d085](https://github.com/microsoft/OpenAPI.NET/commit/1d3d085e0278d9341d7bd10065eba584cb25773c)) +* hidi validate command now logs warnings ([18ed5ac](https://github.com/microsoft/OpenAPI.NET/commit/18ed5acce9661639e1698f19c194e520eb5c93c1)) + + +### Bug Fixes + +* discriminator property validation fails any/allOf cases when it shouldn't ([ff6e411](https://github.com/microsoft/OpenAPI.NET/commit/ff6e4115dcab8c893bbc6b97639fd620b50f105e)) +* discriminator property validation fails any/allOf cases when it shouldn't ([7def73d](https://github.com/microsoft/OpenAPI.NET/commit/7def73d774d1f0e96118e92b636e52cbea371f2d)) + ## [2.4.3](https://github.com/microsoft/OpenAPI.NET/compare/v2.4.2...v2.4.3) (2026-01-16) diff --git a/Directory.Build.props b/Directory.Build.props index 7b6a763dc..a4b8c77a1 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.4.3 + 2.5.0 From f9cf5b807d71c49e5bd7e2bec97f12d3b50ca180 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Wed, 21 Jan 2026 07:41:01 -0800 Subject: [PATCH 5/7] Support mutualTLS security scheme type (#2696) feat(models): support mutualTLS security scheme * fix(writers): throw for mutualTLS in OAS 3.0 --- .../Models/OpenApiSecurityScheme.cs | 16 ++++++++++++++++ .../Models/SecuritySchemeType.cs | 7 ++++++- .../mutualTlsSecurityScheme.yaml | 2 ++ .../Models/OpenApiSecuritySchemeTests.cs | 19 +++++++++++++++++++ .../PublicApi/PublicApi.approved.txt | 2 ++ 5 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 test/Microsoft.OpenApi.Readers.Tests/V32Tests/Samples/OpenApiSecurityScheme/mutualTlsSecurityScheme.yaml diff --git a/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs b/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs index 7d82f3219..50c2ba545 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs @@ -115,6 +115,14 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version // openIdConnectUrl writer.WriteProperty(OpenApiConstants.OpenIdConnectUrl, OpenIdConnectUrl?.ToString()); break; + case SecuritySchemeType.MutualTLS: + // No additional properties for mutualTLS + if (version < OpenApiSpecVersion.OpenApi3_1) + { + // mutualTLS is introduced in OpenAPI 3.1 + throw new OpenApiException($"mutualTLS security scheme is only supported in OpenAPI 3.1 and later versions. Current version: {version}"); + } + break; } // extensions @@ -146,6 +154,14 @@ public virtual void SerializeAsV2(IOpenApiWriter writer) return; } + if (Type == SecuritySchemeType.MutualTLS) + { + // Bail because V2 does not support mutualTLS + writer.WriteStartObject(); + writer.WriteEndObject(); + return; + } + writer.WriteStartObject(); // type diff --git a/src/Microsoft.OpenApi/Models/SecuritySchemeType.cs b/src/Microsoft.OpenApi/Models/SecuritySchemeType.cs index 6c304597a..5640caa9a 100644 --- a/src/Microsoft.OpenApi/Models/SecuritySchemeType.cs +++ b/src/Microsoft.OpenApi/Models/SecuritySchemeType.cs @@ -26,6 +26,11 @@ public enum SecuritySchemeType /// /// Use OAuth2 with OpenId Connect URL to discover OAuth2 configuration value. /// - [Display("openIdConnect")] OpenIdConnect + [Display("openIdConnect")] OpenIdConnect, + + /// + /// Use mutual TLS authentication. + /// + [Display("mutualTLS")] MutualTLS } } diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/Samples/OpenApiSecurityScheme/mutualTlsSecurityScheme.yaml b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/Samples/OpenApiSecurityScheme/mutualTlsSecurityScheme.yaml new file mode 100644 index 000000000..72b4e9ae8 --- /dev/null +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/Samples/OpenApiSecurityScheme/mutualTlsSecurityScheme.yaml @@ -0,0 +1,2 @@ +type: mutualTLS +description: Sample Description diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiSecuritySchemeTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiSecuritySchemeTests.cs index 1415d62a1..0b69e9de7 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiSecuritySchemeTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiSecuritySchemeTests.cs @@ -100,6 +100,12 @@ public class OpenApiSecuritySchemeTests OpenIdConnectUrl = new("https://example.com/openIdConnect") }; + private static OpenApiSecurityScheme MutualTlsSecurityScheme => new() + { + Description = "description1", + Type = SecuritySchemeType.MutualTLS + }; + private static OpenApiSecuritySchemeReference OpenApiSecuritySchemeReference => new("sampleSecurityScheme"); private static OpenApiSecurityScheme ReferencedSecurityScheme => new() { @@ -198,6 +204,19 @@ public async Task SerializeHttpBearerSecuritySchemeAsV3JsonWorks() Assert.Equal(expected, actual); } + [Fact] + public void SerializeMutualTlsSecuritySchemeAsV3Throws() + { + // Arrange + var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); + var writer = new OpenApiJsonWriter(outputStringWriter); + + // Act & Assert + var exception = Assert.Throws(() => MutualTlsSecurityScheme.SerializeAsV3(writer)); + Assert.Contains("mutualTLS security scheme is only supported in OpenAPI 3.1 and later versions", exception.Message); + Assert.Contains($"Current version: {OpenApiSpecVersion.OpenApi3_0}", exception.Message); + } + [Fact] public async Task SerializeOAuthSingleFlowSecuritySchemeAsV3JsonWorks() { diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index d0b8989ef..fc0b3db73 100644 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -1808,6 +1808,8 @@ namespace Microsoft.OpenApi OAuth2 = 2, [Microsoft.OpenApi.Display("openIdConnect")] OpenIdConnect = 3, + [Microsoft.OpenApi.Display("mutualTLS")] + MutualTLS = 4, } public abstract class SourceExpression : Microsoft.OpenApi.RuntimeExpression { From 80e4bbfa4ab31d3af69fe29751714d001c1f9566 Mon Sep 17 00:00:00 2001 From: mdaneri Date: Wed, 21 Jan 2026 08:32:08 -0800 Subject: [PATCH 6/7] feat(models): add shared Content interface (#2695) feat(models): add shared Content interface * Update src/Microsoft.OpenApi/Models/Interfaces/IOpenApiContentElement.cs Co-authored-by: Vincent Biret * Update src/Microsoft.OpenApi/Models/Interfaces/IOpenApiContentElement.cs Co-authored-by: Vincent Biret * Update src/Microsoft.OpenApi/Models/OpenApiHeader.cs Co-authored-by: Vincent Biret * Update src/Microsoft.OpenApi/Models/OpenApiResponse.cs Co-authored-by: Vincent Biret * Remove inheritance from IOpenApiReadOnlyContentElement revert commit 7758a8193a391629d82995881763bba3911b767e * Update src/Microsoft.OpenApi/Models/Interfaces/IOpenApiContentElement.cs Co-authored-by: Vincent Biret * test(publicapi): approve content interface surface --------- Co-authored-by: Vincent Biret Signed-off-by: Vincent Biret --- .../Interfaces/IOpenApiContentElement.cs | 27 ++++++++++++++ .../Models/Interfaces/IOpenApiHeader.cs | 8 +---- .../Models/Interfaces/IOpenApiParameter.cs | 13 +------ .../Models/Interfaces/IOpenApiRequestBody.cs | 7 +--- .../Models/Interfaces/IOpenApiResponse.cs | 8 +---- src/Microsoft.OpenApi/Models/OpenApiHeader.cs | 7 ++-- .../Models/OpenApiParameter.cs | 17 ++++++--- .../Models/OpenApiRequestBody.cs | 19 +++++----- .../Models/OpenApiResponse.cs | 6 ++-- .../PublicApi/PublicApi.approved.txt | 36 ++++++++++--------- 10 files changed, 82 insertions(+), 66 deletions(-) create mode 100644 src/Microsoft.OpenApi/Models/Interfaces/IOpenApiContentElement.cs diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiContentElement.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiContentElement.cs new file mode 100644 index 000000000..15dcd955e --- /dev/null +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiContentElement.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; + +namespace Microsoft.OpenApi; + +/// +/// Describes an element that has content. +/// +public interface IOpenApiContentElement +{ + /// + /// A map containing descriptions of potential payloads. + /// The key is a media type or media type range and the value describes it. + /// + IDictionary? Content { get; set; } +} + +/// +/// Describes an element that has content. +/// +public interface IOpenApiReadOnlyContentElement +{ + /// + /// A map containing descriptions of potential payloads. + /// The key is a media type or media type range and the value describes it. + /// + IDictionary? Content { get; } +} diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiHeader.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiHeader.cs index 04c24b5b2..5f65c39b4 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiHeader.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiHeader.cs @@ -8,7 +8,7 @@ namespace Microsoft.OpenApi; /// Defines the base properties for the headers object. /// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking. /// -public interface IOpenApiHeader : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable, IOpenApiReferenceable +public interface IOpenApiHeader : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable, IOpenApiReferenceable, IOpenApiReadOnlyContentElement { /// /// Determines whether this header is mandatory. @@ -57,10 +57,4 @@ public interface IOpenApiHeader : IOpenApiDescribedElement, IOpenApiReadOnlyExte /// Examples of the media type. /// public IDictionary? Examples { get; } - - /// - /// A map containing the representations for the header. - /// - public IDictionary? Content { get; } - } diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiParameter.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiParameter.cs index 312517acb..405d04fab 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiParameter.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiParameter.cs @@ -7,7 +7,7 @@ namespace Microsoft.OpenApi; /// Defines the base properties for the parameter object. /// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking. /// -public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable, IOpenApiReferenceable +public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable, IOpenApiReferenceable, IOpenApiReadOnlyContentElement { /// /// REQUIRED. The name of the parameter. Parameter names are case sensitive. @@ -93,15 +93,4 @@ public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiReadOnlyE /// Assign to use get null as a serialized value. /// public JsonNode? Example { get; } - - /// - /// A map containing the representations for the parameter. - /// The key is the media type and the value describes it. - /// The map MUST only contain one entry. - /// For more complex scenarios, the content property can define the media type and schema of the parameter. - /// A parameter MUST contain either a schema property, or a content property, but not both. - /// When example or examples are provided in conjunction with the schema object, - /// the example MUST follow the prescribed serialization strategy for the parameter. - /// - public IDictionary? Content { get; } } diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiRequestBody.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiRequestBody.cs index dfe1e1715..2e722b0f5 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiRequestBody.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiRequestBody.cs @@ -6,18 +6,13 @@ namespace Microsoft.OpenApi; /// Defines the base properties for the request body object. /// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking. /// -public interface IOpenApiRequestBody : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable, IOpenApiReferenceable +public interface IOpenApiRequestBody : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable, IOpenApiReferenceable, IOpenApiReadOnlyContentElement { /// /// Determines if the request body is required in the request. Defaults to false. /// public bool Required { get; } - /// - /// REQUIRED. The content of the request body. The key is a media type or media type range and the value describes it. - /// For requests that match multiple keys, only the most specific key is applicable. e.g. text/plain overrides text/* - /// - public IDictionary? Content { get; } /// /// Converts the request body to a body parameter in preparation for a v2 serialization. /// diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiResponse.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiResponse.cs index dfddd7838..07ef60f3d 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiResponse.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiResponse.cs @@ -6,19 +6,13 @@ namespace Microsoft.OpenApi; /// Defines the base properties for the response object. /// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking. /// -public interface IOpenApiResponse : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable, IOpenApiReferenceable +public interface IOpenApiResponse : IOpenApiDescribedElement, IOpenApiReadOnlyExtensible, IShallowCopyable, IOpenApiReferenceable, IOpenApiReadOnlyContentElement { /// /// Maps a header name to its definition. /// public IDictionary? Headers { get; } - /// - /// A map containing descriptions of potential response payloads. - /// The key is a media type or media type range and the value describes it. - /// - public IDictionary? Content { get; } - /// /// A map of operations links that can be followed from the response. /// The key of the map is a short name for the link, diff --git a/src/Microsoft.OpenApi/Models/OpenApiHeader.cs b/src/Microsoft.OpenApi/Models/OpenApiHeader.cs index 8bb155f85..33f119e4d 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiHeader.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiHeader.cs @@ -11,7 +11,7 @@ namespace Microsoft.OpenApi /// Header Object. /// The Header Object follows the structure of the Parameter Object. /// - public class OpenApiHeader : IOpenApiHeader, IOpenApiExtensible + public class OpenApiHeader : IOpenApiHeader, IOpenApiExtensible, IOpenApiContentElement { /// public string? Description { get; set; } @@ -90,7 +90,7 @@ public virtual void SerializeAsV3(IOpenApiWriter writer) SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer)); } - internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version, + internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version, Action callback) { Utils.CheckArgumentNull(writer); @@ -167,7 +167,8 @@ public virtual void SerializeAsV2(IOpenApiWriter writer) writer.WriteProperty(OpenApiConstants.AllowReserved, AllowReserved, false); // schema - var targetSchema = Schema switch { + var targetSchema = Schema switch + { OpenApiSchemaReference schemaReference => schemaReference.RecursiveTarget, OpenApiSchema schema => schema, _ => null, diff --git a/src/Microsoft.OpenApi/Models/OpenApiParameter.cs b/src/Microsoft.OpenApi/Models/OpenApiParameter.cs index 63b3735e2..0ea9ef57b 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiParameter.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiParameter.cs @@ -11,7 +11,7 @@ namespace Microsoft.OpenApi /// /// Parameter Object. /// - public class OpenApiParameter : IOpenApiExtensible, IOpenApiParameter + public class OpenApiParameter : IOpenApiExtensible, IOpenApiParameter, IOpenApiContentElement { private bool? _explode; private ParameterStyle? _style; @@ -60,7 +60,15 @@ public bool Explode /// public JsonNode? Example { get; set; } - /// + /// + /// A map containing the representations for the parameter. + /// The key is the media type and the value describes it. + /// The map MUST only contain one entry. + /// For more complex scenarios, the content property can define the media type and schema of the parameter. + /// A parameter MUST contain either a schema property, or a content property, but not both. + /// When example or examples are provided in conjunction with the schema object, + /// the example MUST follow the prescribed serialization strategy for the parameter. + /// public IDictionary? Content { get; set; } /// @@ -105,7 +113,7 @@ public virtual void SerializeAsV3(IOpenApiWriter writer) SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer)); } - internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version, + internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version, Action callback) { Utils.CheckArgumentNull(writer); @@ -200,7 +208,8 @@ internal virtual void WriteRequestBodySchemaForV2(IOpenApiWriter writer, Diction // uniqueItems // enum // multipleOf - var targetSchema = Schema switch { + var targetSchema = Schema switch + { OpenApiSchemaReference schemaReference => schemaReference.RecursiveTarget, OpenApiSchema schema => schema, _ => null, diff --git a/src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs b/src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs index 8f4c1bd90..73d5e9a98 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs @@ -10,7 +10,7 @@ namespace Microsoft.OpenApi /// /// Request Body Object /// - public class OpenApiRequestBody : IOpenApiExtensible, IOpenApiRequestBody + public class OpenApiRequestBody : IOpenApiExtensible, IOpenApiRequestBody, IOpenApiContentElement { /// public string? Description { get; set; } @@ -18,7 +18,10 @@ public class OpenApiRequestBody : IOpenApiExtensible, IOpenApiRequestBody /// public bool Required { get; set; } - /// + /// + /// REQUIRED. The content of the request body. The key is a media type or media type range and the value describes it. + /// For requests that match multiple keys, only the most specific key is applicable. e.g. text/plain overrides text/* + /// public IDictionary? Content { get; set; } /// @@ -56,7 +59,7 @@ public virtual void SerializeAsV3(IOpenApiWriter writer) { SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer)); } - + internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version, Action callback) { @@ -102,7 +105,7 @@ public IOpenApiParameter ConvertToBodyParameter(IOpenApiWriter writer) Extensions = Extensions?.ToDictionary(static k => k.Key, static v => v.Value) }; // Clone extensions so we can remove the x-bodyName extensions from the output V2 model. - if (bodyParameter.Extensions is not null && + if (bodyParameter.Extensions is not null && bodyParameter.Extensions.TryGetValue(OpenApiConstants.BodyName, out var bodyNameExtension) && bodyNameExtension is JsonNodeExtension bodyName) { @@ -118,7 +121,7 @@ public IEnumerable ConvertToFormDataParameters(IOpenApiWriter if (Content == null || !Content.Any()) yield break; var properties = Content.First().Value.Schema?.Properties; - if(properties != null) + if (properties != null) { foreach (var property in properties) { @@ -136,11 +139,11 @@ public IEnumerable ConvertToFormDataParameters(IOpenApiWriter OpenApiSchemaReference => throw new InvalidOperationException("Unresolved reference target"), _ => throw new InvalidOperationException("Unexpected schema type") }; - + updatedSchema.Type = "file".ToJsonSchemaType(); updatedSchema.Format = null; paramSchema = updatedSchema; - + } yield return new OpenApiFormDataParameter() { @@ -151,7 +154,7 @@ public IEnumerable ConvertToFormDataParameters(IOpenApiWriter Required = Content.First().Value.Schema?.Required?.Contains(property.Key) ?? false }; } - } + } } /// diff --git a/src/Microsoft.OpenApi/Models/OpenApiResponse.cs b/src/Microsoft.OpenApi/Models/OpenApiResponse.cs index 6c1af10f1..4023efaf5 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiResponse.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiResponse.cs @@ -10,7 +10,7 @@ namespace Microsoft.OpenApi /// /// Response object. /// - public class OpenApiResponse : IOpenApiExtensible, IOpenApiResponse + public class OpenApiResponse : IOpenApiExtensible, IOpenApiResponse, IOpenApiContentElement { /// public string? Description { get; set; } @@ -61,7 +61,7 @@ public virtual void SerializeAsV3(IOpenApiWriter writer) SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer)); } - private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version, + private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version, Action callback) { Utils.CheckArgumentNull(writer); @@ -153,7 +153,7 @@ public virtual void SerializeAsV2(IOpenApiWriter writer) // so remove it from the cloned collection so we don't write it again. extensionsClone?.Remove(key); } - } + } } } diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index d0b8989ef..167896e37 100644 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -106,6 +106,10 @@ namespace Microsoft.OpenApi { System.Collections.Generic.Dictionary? PathItems { get; } } + public interface IOpenApiContentElement + { + System.Collections.Generic.IDictionary? Content { get; set; } + } public interface IOpenApiDescribedElement : Microsoft.OpenApi.IOpenApiElement { string? Description { get; set; } @@ -124,11 +128,10 @@ namespace Microsoft.OpenApi { void Write(Microsoft.OpenApi.IOpenApiWriter writer, Microsoft.OpenApi.OpenApiSpecVersion specVersion); } - public interface IOpenApiHeader : Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable + public interface IOpenApiHeader : Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyContentElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable { bool AllowEmptyValue { get; } bool AllowReserved { get; } - System.Collections.Generic.IDictionary? Content { get; } bool Deprecated { get; } System.Text.Json.Nodes.JsonNode? Example { get; } System.Collections.Generic.IDictionary? Examples { get; } @@ -145,11 +148,10 @@ namespace Microsoft.OpenApi Microsoft.OpenApi.RuntimeExpressionAnyWrapper? RequestBody { get; } Microsoft.OpenApi.OpenApiServer? Server { get; } } - public interface IOpenApiParameter : Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable + public interface IOpenApiParameter : Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyContentElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable { bool AllowEmptyValue { get; } bool AllowReserved { get; } - System.Collections.Generic.IDictionary? Content { get; } bool Deprecated { get; } System.Text.Json.Nodes.JsonNode? Example { get; } System.Collections.Generic.IDictionary? Examples { get; } @@ -166,6 +168,10 @@ namespace Microsoft.OpenApi System.Collections.Generic.IList? Parameters { get; } System.Collections.Generic.IList? Servers { get; } } + public interface IOpenApiReadOnlyContentElement + { + System.Collections.Generic.IDictionary? Content { get; } + } public interface IOpenApiReadOnlyDescribedElement : Microsoft.OpenApi.IOpenApiElement { string? Description { get; } @@ -199,16 +205,14 @@ namespace Microsoft.OpenApi U CopyReferenceAsTargetElementWithOverrides(U source); } public interface IOpenApiReferenceable : Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiSerializable { } - public interface IOpenApiRequestBody : Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable + public interface IOpenApiRequestBody : Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyContentElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable { - System.Collections.Generic.IDictionary? Content { get; } bool Required { get; } Microsoft.OpenApi.IOpenApiParameter? ConvertToBodyParameter(Microsoft.OpenApi.IOpenApiWriter writer); System.Collections.Generic.IEnumerable? ConvertToFormDataParameters(Microsoft.OpenApi.IOpenApiWriter writer); } - public interface IOpenApiResponse : Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable + public interface IOpenApiResponse : Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyContentElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable { - System.Collections.Generic.IDictionary? Content { get; } System.Collections.Generic.IDictionary? Headers { get; } System.Collections.Generic.IDictionary? Links { get; } } @@ -736,7 +740,7 @@ namespace Microsoft.OpenApi public static Microsoft.OpenApi.OpenApiUrlTreeNode CreateOpenApiUrlTreeNode(System.Collections.Generic.Dictionary sources) { } public static System.Func CreatePredicate(string? operationIds = null, string? tags = null, System.Collections.Generic.Dictionary>? requestUrls = null, Microsoft.OpenApi.OpenApiDocument? source = null) { } } - public class OpenApiHeader : Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiExtensible, Microsoft.OpenApi.IOpenApiHeader, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable + public class OpenApiHeader : Microsoft.OpenApi.IOpenApiContentElement, Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiExtensible, Microsoft.OpenApi.IOpenApiHeader, Microsoft.OpenApi.IOpenApiReadOnlyContentElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable { public OpenApiHeader() { } public bool AllowEmptyValue { get; set; } @@ -756,7 +760,7 @@ namespace Microsoft.OpenApi public virtual void SerializeAsV3(Microsoft.OpenApi.IOpenApiWriter writer) { } public virtual void SerializeAsV31(Microsoft.OpenApi.IOpenApiWriter writer) { } } - public class OpenApiHeaderReference : Microsoft.OpenApi.BaseOpenApiReferenceHolder, Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiHeader, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable + public class OpenApiHeaderReference : Microsoft.OpenApi.BaseOpenApiReferenceHolder, Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiHeader, Microsoft.OpenApi.IOpenApiReadOnlyContentElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable { public OpenApiHeaderReference(string referenceId, Microsoft.OpenApi.OpenApiDocument? hostDocument = null, string? externalResource = null) { } public bool AllowEmptyValue { get; } @@ -941,7 +945,7 @@ namespace Microsoft.OpenApi public virtual void SerializeAsV3(Microsoft.OpenApi.IOpenApiWriter writer) { } public virtual void SerializeAsV31(Microsoft.OpenApi.IOpenApiWriter writer) { } } - public class OpenApiParameter : Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiExtensible, Microsoft.OpenApi.IOpenApiParameter, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable + public class OpenApiParameter : Microsoft.OpenApi.IOpenApiContentElement, Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiExtensible, Microsoft.OpenApi.IOpenApiParameter, Microsoft.OpenApi.IOpenApiReadOnlyContentElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable { public OpenApiParameter() { } public bool AllowEmptyValue { get; set; } @@ -963,7 +967,7 @@ namespace Microsoft.OpenApi public virtual void SerializeAsV3(Microsoft.OpenApi.IOpenApiWriter writer) { } public virtual void SerializeAsV31(Microsoft.OpenApi.IOpenApiWriter writer) { } } - public class OpenApiParameterReference : Microsoft.OpenApi.BaseOpenApiReferenceHolder, Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiParameter, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable + public class OpenApiParameterReference : Microsoft.OpenApi.BaseOpenApiReferenceHolder, Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiParameter, Microsoft.OpenApi.IOpenApiReadOnlyContentElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable { public OpenApiParameterReference(string referenceId, Microsoft.OpenApi.OpenApiDocument? hostDocument = null, string? externalResource = null) { } public bool AllowEmptyValue { get; } @@ -1065,7 +1069,7 @@ namespace Microsoft.OpenApi protected override void SerializeAdditionalV31Properties(Microsoft.OpenApi.IOpenApiWriter writer) { } protected override void SetAdditional31MetadataFromMapNode(System.Text.Json.Nodes.JsonObject jsonObject) { } } - public class OpenApiRequestBody : Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiExtensible, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiRequestBody, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable + public class OpenApiRequestBody : Microsoft.OpenApi.IOpenApiContentElement, Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiExtensible, Microsoft.OpenApi.IOpenApiReadOnlyContentElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiRequestBody, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable { public OpenApiRequestBody() { } public System.Collections.Generic.IDictionary? Content { get; set; } @@ -1079,7 +1083,7 @@ namespace Microsoft.OpenApi public virtual void SerializeAsV3(Microsoft.OpenApi.IOpenApiWriter writer) { } public virtual void SerializeAsV31(Microsoft.OpenApi.IOpenApiWriter writer) { } } - public class OpenApiRequestBodyReference : Microsoft.OpenApi.BaseOpenApiReferenceHolder, Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiRequestBody, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable + public class OpenApiRequestBodyReference : Microsoft.OpenApi.BaseOpenApiReferenceHolder, Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyContentElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiRequestBody, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable { public OpenApiRequestBodyReference(string referenceId, Microsoft.OpenApi.OpenApiDocument? hostDocument = null, string? externalResource = null) { } public System.Collections.Generic.IDictionary? Content { get; } @@ -1093,7 +1097,7 @@ namespace Microsoft.OpenApi public Microsoft.OpenApi.IOpenApiRequestBody CreateShallowCopy() { } public override void SerializeAsV2(Microsoft.OpenApi.IOpenApiWriter writer) { } } - public class OpenApiResponse : Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiExtensible, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiResponse, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable + public class OpenApiResponse : Microsoft.OpenApi.IOpenApiContentElement, Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiExtensible, Microsoft.OpenApi.IOpenApiReadOnlyContentElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiResponse, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable { public OpenApiResponse() { } public System.Collections.Generic.IDictionary? Content { get; set; } @@ -1106,7 +1110,7 @@ namespace Microsoft.OpenApi public virtual void SerializeAsV3(Microsoft.OpenApi.IOpenApiWriter writer) { } public virtual void SerializeAsV31(Microsoft.OpenApi.IOpenApiWriter writer) { } } - public class OpenApiResponseReference : Microsoft.OpenApi.BaseOpenApiReferenceHolder, Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiResponse, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable + public class OpenApiResponseReference : Microsoft.OpenApi.BaseOpenApiReferenceHolder, Microsoft.OpenApi.IOpenApiDescribedElement, Microsoft.OpenApi.IOpenApiElement, Microsoft.OpenApi.IOpenApiReadOnlyContentElement, Microsoft.OpenApi.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.IOpenApiReferenceable, Microsoft.OpenApi.IOpenApiResponse, Microsoft.OpenApi.IOpenApiSerializable, Microsoft.OpenApi.IShallowCopyable { public OpenApiResponseReference(string referenceId, Microsoft.OpenApi.OpenApiDocument? hostDocument = null, string? externalResource = null) { } public System.Collections.Generic.IDictionary? Content { get; } From 67899ae3c64615be6e743594cd01b63a70e9ff0d Mon Sep 17 00:00:00 2001 From: "release-please-token-provider[bot]" <225477224+release-please-token-provider[bot]@users.noreply.github.com> Date: Wed, 21 Jan 2026 17:55:22 +0000 Subject: [PATCH 7/7] chore(support/v2): release 2.6.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 10 ++++++++++ Directory.Build.props | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 4dedeaebc..511dd5165 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.5.0" + ".": "2.6.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 3098a8f17..00819c348 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## [2.6.0](https://github.com/microsoft/OpenAPI.NET/compare/v2.5.0...v2.6.0) (2026-01-21) + + +### Features + +* **models:** add shared Content interface ([80e4bbf](https://github.com/microsoft/OpenAPI.NET/commit/80e4bbfa4ab31d3af69fe29751714d001c1f9566)) +* **models:** add shared Content interface ([#2695](https://github.com/microsoft/OpenAPI.NET/issues/2695)) ([338566f](https://github.com/microsoft/OpenAPI.NET/commit/338566fafce04ee1329f4ead61fe1e87e01144ad)) +* **models:** add shared Content interface ([#2695](https://github.com/microsoft/OpenAPI.NET/issues/2695)) ([80e4bbf](https://github.com/microsoft/OpenAPI.NET/commit/80e4bbfa4ab31d3af69fe29751714d001c1f9566)) +* **models:** support mutualTLS security scheme ([f9cf5b8](https://github.com/microsoft/OpenAPI.NET/commit/f9cf5b807d71c49e5bd7e2bec97f12d3b50ca180)) + ## [2.5.0](https://github.com/microsoft/OpenAPI.NET/compare/v2.4.3...v2.5.0) (2026-01-19) diff --git a/Directory.Build.props b/Directory.Build.props index a4b8c77a1..76cd2b183 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.5.0 + 2.6.0