From 9d07ebb4b70bdd641748270a831df031d35b7ec4 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 8 Jan 2025 15:52:38 -0500 Subject: [PATCH 1/2] fix: enum parsing when encountering unknown values should not default to first member --- .../Extensions/StringExtensions.cs | 52 ++++++++++++------- .../Models/OpenApiSecurityScheme.cs | 10 ++-- .../OpenApiSecuritySchemeReference.cs | 4 +- .../Reader/V2/OpenApiParameterDeserializer.cs | 3 +- .../V2/OpenApiSecuritySchemeDeserializer.cs | 14 ++++- .../Reader/V3/OpenApiEncodingDeserializer.cs | 9 +++- .../Reader/V3/OpenApiHeaderDeserializer.cs | 9 +++- .../Reader/V3/OpenApiParameterDeserializer.cs | 19 ++++--- .../V3/OpenApiSecuritySchemeDeserializer.cs | 19 +++++-- .../Reader/V3/OpenApiV3VersionService.cs | 29 +++++------ .../Reader/V31/OpenApiEncodingDeserializer.cs | 6 ++- .../Reader/V31/OpenApiHeaderDeserializer.cs | 6 ++- .../V31/OpenApiParameterDeserializer.cs | 16 +++--- .../V31/OpenApiSecuritySchemeDeserializer.cs | 12 ++++- .../Reader/V31/OpenApiV31VersionService.cs | 4 +- .../Attributes/DisplayAttributeTests.cs | 6 ++- .../PublicApi/PublicApi.approved.txt | 12 ++--- 17 files changed, 153 insertions(+), 77 deletions(-) diff --git a/src/Microsoft.OpenApi/Extensions/StringExtensions.cs b/src/Microsoft.OpenApi/Extensions/StringExtensions.cs index 00c26575e..1678f26dd 100644 --- a/src/Microsoft.OpenApi/Extensions/StringExtensions.cs +++ b/src/Microsoft.OpenApi/Extensions/StringExtensions.cs @@ -2,47 +2,61 @@ // Licensed under the MIT license. using System; using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using System.Reflection; using Microsoft.OpenApi.Attributes; +using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Reader; namespace Microsoft.OpenApi.Extensions { /// /// String extension methods. /// - public static class StringExtensions + internal static class StringExtensions { - private static readonly ConcurrentDictionary> EnumDisplayCache = new(); + private static readonly ConcurrentDictionary> EnumDisplayCache = new(); - /// - /// Gets the enum value based on the given enum type and display name. - /// - /// The display name. - public static T GetEnumFromDisplayName<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] T>(this string displayName) + internal static bool TryGetEnumFromDisplayName<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] T>(this string displayName, ParsingContext parsingContext, out T result) where T : Enum + { + if (TryGetEnumFromDisplayName(displayName, out result)) + { + return true; + } + + parsingContext.Diagnostic.Errors.Add(new OpenApiError(parsingContext.GetLocation(), $"Enum value {displayName} is not recognized.")); + return false; + + } + internal static bool TryGetEnumFromDisplayName<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] T>(this string displayName, out T result) where T : Enum { var type = typeof(T); - if (!type.IsEnum) - return default; - var displayMap = EnumDisplayCache.GetOrAdd(type, _ => new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase)); + var displayMap = EnumDisplayCache.GetOrAdd(type, GetEnumValues); if (displayMap.TryGetValue(displayName, out var cachedValue)) - return (T)cachedValue; - + { + result = (T)cachedValue; + return true; + } - foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.Static)) + result = default; + return false; + } + private static ReadOnlyDictionary GetEnumValues(Type enumType) where T : Enum + { + var result = new Dictionary(StringComparer.OrdinalIgnoreCase); + foreach (var field in enumType.GetFields(BindingFlags.Public | BindingFlags.Static)) { - var displayAttribute = field.GetCustomAttribute(); - if (displayAttribute != null && displayAttribute.Name.Equals(displayName, StringComparison.OrdinalIgnoreCase)) + if (field.GetCustomAttribute() is {} displayAttribute) { var enumValue = (T)field.GetValue(null); - displayMap.TryAdd(displayName, enumValue); - return enumValue; + result.Add(displayAttribute.Name, enumValue); } } - - return default; + return new ReadOnlyDictionary(result); } internal static string ToFirstCharacterLowerCase(this string input) => string.IsNullOrEmpty(input) ? string.Empty : char.ToLowerInvariant(input[0]) + input.Substring(1); diff --git a/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs b/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs index 33a07beda..d9227be25 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs @@ -17,7 +17,7 @@ public class OpenApiSecurityScheme : IOpenApiReferenceable, IOpenApiExtensible /// /// REQUIRED. The type of the security scheme. Valid values are "apiKey", "http", "oauth2", "openIdConnect". /// - public virtual SecuritySchemeType Type { get; set; } + public virtual SecuritySchemeType? Type { get; set; } /// /// A short description for security scheme. CommonMark syntax MAY be used for rich text representation. @@ -32,7 +32,7 @@ public class OpenApiSecurityScheme : IOpenApiReferenceable, IOpenApiExtensible /// /// REQUIRED. The location of the API key. Valid values are "query", "header" or "cookie". /// - public virtual ParameterLocation In { get; set; } + public virtual ParameterLocation? In { get; set; } /// /// REQUIRED. The name of the HTTP Authorization scheme to be used @@ -82,10 +82,10 @@ public OpenApiSecurityScheme() { } /// public OpenApiSecurityScheme(OpenApiSecurityScheme securityScheme) { - Type = securityScheme?.Type ?? Type; + Type = securityScheme?.Type; Description = securityScheme?.Description ?? Description; Name = securityScheme?.Name ?? Name; - In = securityScheme?.In ?? In; + In = securityScheme?.In; Scheme = securityScheme?.Scheme ?? Scheme; BearerFormat = securityScheme?.BearerFormat ?? BearerFormat; Flows = securityScheme?.Flows != null ? new(securityScheme?.Flows) : null; @@ -111,7 +111,7 @@ public virtual void SerializeAsV3(IOpenApiWriter writer) SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer)); } - internal virtual void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version, + internal virtual void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version, Action callback) { Utils.CheckArgumentNull(writer); diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiSecuritySchemeReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiSecuritySchemeReference.cs index e635de6f9..faf6ae3bc 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiSecuritySchemeReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiSecuritySchemeReference.cs @@ -71,7 +71,7 @@ public override string Description public override string Name { get => Target.Name; set => Target.Name = value; } /// - public override ParameterLocation In { get => Target.In; set => Target.In = value; } + public override ParameterLocation? In { get => Target.In; set => Target.In = value; } /// public override string Scheme { get => Target.Scheme; set => Target.Scheme = value; } @@ -89,7 +89,7 @@ public override string Description public override IDictionary Extensions { get => Target.Extensions; set => Target.Extensions = value; } /// - public override SecuritySchemeType Type { get => Target.Type; set => Target.Type = value; } + public override SecuritySchemeType? Type { get => Target.Type; set => Target.Type = value; } /// public override void SerializeAsV3(IOpenApiWriter writer) diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs index 149c00fd3..da1766cbe 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs @@ -172,7 +172,8 @@ private static void ProcessIn(OpenApiParameter o, ParseNode n, OpenApiDocument h case "query": case "header": case "path": - o.In = value.GetEnumFromDisplayName(); + value.TryGetEnumFromDisplayName(out var _in); + o.In = _in; break; default: o.In = null; diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiSecuritySchemeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiSecuritySchemeDeserializer.cs index 4e142b479..91d783bce 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiSecuritySchemeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiSecuritySchemeDeserializer.cs @@ -40,12 +40,24 @@ internal static partial class OpenApiV2Deserializer case "oauth2": o.Type = SecuritySchemeType.OAuth2; break; + + default: + n.Context.Diagnostic.Errors.Add(new OpenApiError(n.Context.GetLocation(), $"Security scheme type {type} is not recognized.")); + break; } } }, {"description", (o, n, _) => o.Description = n.GetScalarValue()}, {"name", (o, n, _) => o.Name = n.GetScalarValue()}, - {"in", (o, n, _) => o.In = n.GetScalarValue().GetEnumFromDisplayName()}, + {"in", (o, n, _) => + { + if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var _in)) + { + return; + } + o.In = _in; + } + }, { "flow", (_, n, _) => _flowValue = n.GetScalarValue() }, diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiEncodingDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiEncodingDeserializer.cs index 67cb19ecb..6bd486e7a 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiEncodingDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiEncodingDeserializer.cs @@ -25,7 +25,14 @@ internal static partial class OpenApiV3Deserializer }, { "style", - (o, n, _) => o.Style = n.GetScalarValue().GetEnumFromDisplayName() + (o, n, _) => + { + if(!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var style)) + { + return; + } + o.Style = style; + } }, { "explode", diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs index bc09b9b10..8f6edb55b 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs @@ -39,7 +39,14 @@ internal static partial class OpenApiV3Deserializer }, { "style", - (o, n, _) => o.Style = n.GetScalarValue().GetEnumFromDisplayName() + (o, n, _) => + { + if(!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var style)) + { + return; + } + o.Style = style; + } }, { "explode", diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs index 0446c52b7..74edfd462 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs @@ -26,11 +26,11 @@ internal static partial class OpenApiV3Deserializer { "in", (o, n, _) => { - var inString = n.GetScalarValue(); - - o.In = Enum.GetValues(typeof(ParameterLocation)).Cast() - .Select( e => e.GetDisplayName() ) - .Contains(inString) ? n.GetScalarValue().GetEnumFromDisplayName() : null; + if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var _in)) + { + return; + } + o.In = _in; } }, { @@ -55,7 +55,14 @@ internal static partial class OpenApiV3Deserializer }, { "style", - (o, n, _) => o.Style = n.GetScalarValue().GetEnumFromDisplayName() + (o, n, _) => + { + if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var style)) + { + return; + } + o.Style = style; + } }, { "explode", diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiSecuritySchemeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiSecuritySchemeDeserializer.cs index 4a794408a..0659b4c22 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiSecuritySchemeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiSecuritySchemeDeserializer.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. using System; -using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models.References; @@ -21,7 +20,14 @@ internal static partial class OpenApiV3Deserializer { { "type", - (o, n, _) => o.Type = n.GetScalarValue().GetEnumFromDisplayName() + (o, n, _) => + { + if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var type)) + { + return; + } + o.Type = type; + } }, { "description", @@ -33,7 +39,14 @@ internal static partial class OpenApiV3Deserializer }, { "in", - (o, n, _) => o.In = n.GetScalarValue().GetEnumFromDisplayName() + (o, n, _) => + { + if(!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var _in)) + { + return; + } + o.In = _in; + } }, { "scheme", diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs index c2ef954a5..9ac257814 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs @@ -123,7 +123,7 @@ public OpenApiReference ConvertToOpenApiReference( if (id.StartsWith("/components/")) { var localSegments = segments[1].Split('/'); - var referencedType = localSegments[2].GetEnumFromDisplayName(); + localSegments[2].TryGetEnumFromDisplayName(out var referencedType); if (type == null) { type = referencedType; @@ -200,25 +200,22 @@ private OpenApiReference ParseLocalReference(string localReference) var segments = localReference.Split('/'); - if (segments.Length == 4) // /components/{type}/pet + if (segments.Length == 4 && segments[1] == "components") // /components/{type}/pet { - if (segments[1] == "components") + segments[2].TryGetEnumFromDisplayName(out var referenceType); + var refId = segments[3]; + if (segments[2] == "pathItems") { - var referenceType = segments[2].GetEnumFromDisplayName(); - var refId = segments[3]; - if (segments[2] == "pathItems") - { - refId = "/" + segments[3]; - }; + refId = "/" + segments[3]; + } - var parsedReference = new OpenApiReference - { - Type = referenceType, - Id = refId - }; + var parsedReference = new OpenApiReference + { + Type = referenceType, + Id = refId + }; - return parsedReference; - } + return parsedReference; } throw new OpenApiException(string.Format(SRResource.ReferenceHasInvalidFormat, localReference)); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs index b54c5e75b..d676b1a59 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs @@ -27,7 +27,11 @@ internal static partial class OpenApiV31Deserializer { "style", (o, n, _) => { - o.Style = n.GetScalarValue().GetEnumFromDisplayName(); + if(!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var style)) + { + return; + } + o.Style = style; } }, { diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs index d3657db02..7349774f6 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs @@ -47,7 +47,11 @@ internal static partial class OpenApiV31Deserializer { "style", (o, n, _) => { - o.Style = n.GetScalarValue().GetEnumFromDisplayName(); + if(!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var style)) + { + return; + } + o.Style = style; } }, { diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs index e8f4e5a93..824e6e577 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs @@ -25,11 +25,11 @@ internal static partial class OpenApiV31Deserializer { "in", (o, n, _) => { - var inString = n.GetScalarValue(); - o.In = Enum.GetValues(typeof(ParameterLocation)).Cast() - .Select( e => e.GetDisplayName() ) - .Contains(inString) ? n.GetScalarValue().GetEnumFromDisplayName() : null; - + if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var _in)) + { + return; + } + o.In = _in; } }, { @@ -65,7 +65,11 @@ internal static partial class OpenApiV31Deserializer { "style", (o, n, _) => { - o.Style = n.GetScalarValue().GetEnumFromDisplayName(); + if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var style)) + { + return; + } + o.Style = style; } }, { diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiSecuritySchemeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiSecuritySchemeDeserializer.cs index 7b5ff5cb8..8fb5c0cd1 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiSecuritySchemeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiSecuritySchemeDeserializer.cs @@ -22,7 +22,11 @@ internal static partial class OpenApiV31Deserializer { "type", (o, n, _) => { - o.Type = n.GetScalarValue().GetEnumFromDisplayName(); + if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var type)) + { + return; + } + o.Type = type; } }, { @@ -40,7 +44,11 @@ internal static partial class OpenApiV31Deserializer { "in", (o, n, _) => { - o.In = n.GetScalarValue().GetEnumFromDisplayName(); + if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var _in)) + { + return; + } + o.In = _in; } }, { diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs index 333ec53bb..f564c37ab 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs @@ -124,7 +124,7 @@ public OpenApiReference ConvertToOpenApiReference( if (id.StartsWith("/components/")) { var localSegments = segments[1].Split('/'); - var referencedType = localSegments[2].GetEnumFromDisplayName(); + localSegments[2].TryGetEnumFromDisplayName(out var referencedType); if (type == null) { type = referencedType; @@ -188,7 +188,7 @@ private OpenApiReference ParseLocalReference(string localReference, string summa if (segments.Length == 4 && segments[1] == "components") // /components/{type}/pet { - var referenceType = segments[2].GetEnumFromDisplayName(); + segments[2].TryGetEnumFromDisplayName(out var referenceType); var refId = segments[3]; if (segments[2] == "pathItems") { diff --git a/test/Microsoft.OpenApi.Tests/Attributes/DisplayAttributeTests.cs b/test/Microsoft.OpenApi.Tests/Attributes/DisplayAttributeTests.cs index 182108260..4ce1c644a 100644 --- a/test/Microsoft.OpenApi.Tests/Attributes/DisplayAttributeTests.cs +++ b/test/Microsoft.OpenApi.Tests/Attributes/DisplayAttributeTests.cs @@ -45,7 +45,8 @@ public void GetDisplayNameExtensionShouldUseDisplayAttribute(ApiLevel apiLevel, [InlineData(ApiLevel.Corporate, "corporate")] public void GetEnumFromDisplayNameShouldReturnEnumValue(ApiLevel expected, string displayName) { - Assert.Equal(expected, displayName.GetEnumFromDisplayName()); + displayName.TryGetEnumFromDisplayName(out var result); + Assert.Equal(expected, result); } [Theory] @@ -54,7 +55,8 @@ public void GetEnumFromDisplayNameShouldReturnEnumValue(ApiLevel expected, strin [InlineData(UserType.Editor, "editor")] public void GetEnumFromDisplayNameShouldReturnEnumValueForFlagsEnum(UserType expected, string displayName) { - Assert.Equal(expected, displayName.GetEnumFromDisplayName()); + displayName.TryGetEnumFromDisplayName(out var result); + Assert.Equal(expected, result); } } } diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index 88599f6ef..d57cb34ff 100644 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -196,10 +196,6 @@ namespace Microsoft.OpenApi.Extensions public static string? ToIdentifier(this Microsoft.OpenApi.Models.JsonSchemaType? schemaType) { } public static Microsoft.OpenApi.Models.JsonSchemaType ToJsonSchemaType(this string identifier) { } } - public static class StringExtensions - { - public static T GetEnumFromDisplayName(this string displayName) { } - } } namespace Microsoft.OpenApi.Interfaces { @@ -949,11 +945,11 @@ namespace Microsoft.OpenApi.Models public virtual string Description { get; set; } public virtual System.Collections.Generic.IDictionary Extensions { get; set; } public virtual Microsoft.OpenApi.Models.OpenApiOAuthFlows Flows { get; set; } - public virtual Microsoft.OpenApi.Models.ParameterLocation In { get; set; } + public virtual Microsoft.OpenApi.Models.ParameterLocation? In { get; set; } public virtual string Name { get; set; } public virtual System.Uri OpenIdConnectUrl { get; set; } public virtual string Scheme { get; set; } - public virtual Microsoft.OpenApi.Models.SecuritySchemeType Type { get; set; } + public virtual Microsoft.OpenApi.Models.SecuritySchemeType? Type { get; set; } public virtual void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -1274,11 +1270,11 @@ namespace Microsoft.OpenApi.Models.References public override string Description { get; set; } public override System.Collections.Generic.IDictionary Extensions { get; set; } public override Microsoft.OpenApi.Models.OpenApiOAuthFlows Flows { get; set; } - public override Microsoft.OpenApi.Models.ParameterLocation In { get; set; } + public override Microsoft.OpenApi.Models.ParameterLocation? In { get; set; } public override string Name { get; set; } public override System.Uri OpenIdConnectUrl { get; set; } public override string Scheme { get; set; } - public override Microsoft.OpenApi.Models.SecuritySchemeType Type { get; set; } + public override Microsoft.OpenApi.Models.SecuritySchemeType? Type { get; set; } public override void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public override void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public override void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } From fd25660595082b32d4414d8f10e450d4275974ae Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 8 Jan 2025 15:57:41 -0500 Subject: [PATCH 2/2] chore: aligns parsing pattern --- .../Reader/V2/OpenApiParameterDeserializer.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs index da1766cbe..99f65fdb2 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs @@ -172,8 +172,10 @@ private static void ProcessIn(OpenApiParameter o, ParseNode n, OpenApiDocument h case "query": case "header": case "path": - value.TryGetEnumFromDisplayName(out var _in); - o.In = _in; + if (value.TryGetEnumFromDisplayName(out var _in)) + { + o.In = _in; + } break; default: o.In = null;