From c4ee9ff5157a13237b031cafacd29e077f9fcf2e Mon Sep 17 00:00:00 2001 From: "Gavin Barron (from Dev Box)" Date: Fri, 9 Jan 2026 11:43:46 -0800 Subject: [PATCH 1/2] feat: add switch to use put as default update verb --- .../OpenApiConvertSettings.cs | 12 ++++++- .../PathItem/ComplexPropertyItemHandler.cs | 11 ++++++- .../PathItem/EntityPathItemHandler.cs | 11 ++++++- .../NavigationPropertyPathItemHandler.cs | 11 ++++++- .../PublicAPI.Unshipped.txt | 2 ++ src/OoasUtil/ComLineProcessor.cs | 32 +++++++++++++++++++ src/OoasUtil/Program.cs | 1 + 7 files changed, 76 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.OpenApi.OData.Reader/OpenApiConvertSettings.cs b/src/Microsoft.OpenApi.OData.Reader/OpenApiConvertSettings.cs index a7021c44..4ea0a38e 100644 --- a/src/Microsoft.OpenApi.OData.Reader/OpenApiConvertSettings.cs +++ b/src/Microsoft.OpenApi.OData.Reader/OpenApiConvertSettings.cs @@ -337,6 +337,15 @@ public string? PathPrefix /// public int ComposableFunctionsExpansionDepth { get; set; } = 1; + /// + /// Gets/sets a value indicating whether to use HTTP PUT method for update operations by default + /// instead of PATCH when no UpdateRestrictions annotation is present in the CSDL. + /// If false (default), PATCH will be used for updates. + /// If true, PUT will be used for updates. + /// This setting is ignored when UpdateRestrictions annotations are present in the CSDL. + /// + public bool UseHttpPutForUpdate { get; set; } = false; + internal OpenApiConvertSettings Clone() { var newSettings = new OpenApiConvertSettings @@ -392,7 +401,8 @@ internal OpenApiConvertSettings Clone() SemVerVersion = this.SemVerVersion, EnableAliasForOperationSegments = this.EnableAliasForOperationSegments, UseStringArrayForQueryOptionsSchema = this.UseStringArrayForQueryOptionsSchema, - ComposableFunctionsExpansionDepth = this.ComposableFunctionsExpansionDepth + ComposableFunctionsExpansionDepth = this.ComposableFunctionsExpansionDepth, + UseHttpPutForUpdate = this.UseHttpPutForUpdate }; return newSettings; diff --git a/src/Microsoft.OpenApi.OData.Reader/PathItem/ComplexPropertyItemHandler.cs b/src/Microsoft.OpenApi.OData.Reader/PathItem/ComplexPropertyItemHandler.cs index 6596750e..1e4e7a83 100644 --- a/src/Microsoft.OpenApi.OData.Reader/PathItem/ComplexPropertyItemHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/PathItem/ComplexPropertyItemHandler.cs @@ -99,7 +99,16 @@ public void AddUpdateOperation(OpenApiPathItem item) } else { - AddOperation(item, HttpMethod.Patch); + // When no explicit update method is specified in UpdateRestrictions, + // use the UseHttpPutForUpdate setting to determine the default method + if (Context?.Settings?.UseHttpPutForUpdate == true) + { + AddOperation(item, HttpMethod.Put); + } + else + { + AddOperation(item, HttpMethod.Patch); + } } } } diff --git a/src/Microsoft.OpenApi.OData.Reader/PathItem/EntityPathItemHandler.cs b/src/Microsoft.OpenApi.OData.Reader/PathItem/EntityPathItemHandler.cs index 0487f787..0d4dbdbd 100644 --- a/src/Microsoft.OpenApi.OData.Reader/PathItem/EntityPathItemHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/PathItem/EntityPathItemHandler.cs @@ -67,7 +67,16 @@ protected override void SetOperations(OpenApiPathItem item) } else { - AddOperation(item, HttpMethod.Patch); + // When no explicit update method is specified in UpdateRestrictions, + // use the UseHttpPutForUpdate setting to determine the default method + if (Context?.Settings?.UseHttpPutForUpdate == true) + { + AddOperation(item, HttpMethod.Put); + } + else + { + AddOperation(item, HttpMethod.Patch); + } } } diff --git a/src/Microsoft.OpenApi.OData.Reader/PathItem/NavigationPropertyPathItemHandler.cs b/src/Microsoft.OpenApi.OData.Reader/PathItem/NavigationPropertyPathItemHandler.cs index a1c33b15..a86fc5da 100644 --- a/src/Microsoft.OpenApi.OData.Reader/PathItem/NavigationPropertyPathItemHandler.cs +++ b/src/Microsoft.OpenApi.OData.Reader/PathItem/NavigationPropertyPathItemHandler.cs @@ -279,7 +279,16 @@ private void AddUpdateOperation(OpenApiPathItem item, UpdateRestrictionsType? up } else { - AddOperation(item, HttpMethod.Patch); + // When no explicit update method is specified in UpdateRestrictions, + // use the UseHttpPutForUpdate setting to determine the default method + if (Context?.Settings?.UseHttpPutForUpdate == true) + { + AddOperation(item, HttpMethod.Put); + } + else + { + AddOperation(item, HttpMethod.Patch); + } } } diff --git a/src/Microsoft.OpenApi.OData.Reader/PublicAPI.Unshipped.txt b/src/Microsoft.OpenApi.OData.Reader/PublicAPI.Unshipped.txt index e29f3677..ee063ec9 100644 --- a/src/Microsoft.OpenApi.OData.Reader/PublicAPI.Unshipped.txt +++ b/src/Microsoft.OpenApi.OData.Reader/PublicAPI.Unshipped.txt @@ -221,6 +221,8 @@ Microsoft.OpenApi.OData.OpenApiConvertSettings.UseStringArrayForQueryOptionsSche Microsoft.OpenApi.OData.OpenApiConvertSettings.UseStringArrayForQueryOptionsSchema.set -> void Microsoft.OpenApi.OData.OpenApiConvertSettings.UseSuccessStatusCodeRange.get -> bool Microsoft.OpenApi.OData.OpenApiConvertSettings.UseSuccessStatusCodeRange.set -> void +Microsoft.OpenApi.OData.OpenApiConvertSettings.UseHttpPutForUpdate.get -> bool +Microsoft.OpenApi.OData.OpenApiConvertSettings.UseHttpPutForUpdate.set -> void Microsoft.OpenApi.OData.OpenApiConvertSettings.VerifyEdmModel.get -> bool Microsoft.OpenApi.OData.OpenApiConvertSettings.VerifyEdmModel.set -> void Microsoft.OpenApi.OData.Vocabulary.Core.LinkRelKey diff --git a/src/OoasUtil/ComLineProcessor.cs b/src/OoasUtil/ComLineProcessor.cs index 84cb58c3..b8169d50 100644 --- a/src/OoasUtil/ComLineProcessor.cs +++ b/src/OoasUtil/ComLineProcessor.cs @@ -99,6 +99,11 @@ public ComLineProcessor(string[] args) /// public bool? RequireDerivedTypesConstraint { get; private set; } + /// + /// Use HTTP PUT method for update operations by default instead of PATCH. + /// + public bool? UseHttpPutForUpdate { get; private set; } + /// /// Process the arguments. /// @@ -227,6 +232,14 @@ public bool Process() } break; + case "--useputforupdate": + case "-put": + if (!ProcessUseHttpPutForUpdate(true)) + { + return false; + } + break; + default: PrintUsage(); return false; @@ -285,6 +298,11 @@ public bool Process() DisableSchemaExamples = false; } + if (UseHttpPutForUpdate == null) + { + UseHttpPutForUpdate = false; + } + _continue = ValidateArguments(); return _continue; } @@ -419,6 +437,19 @@ private bool ProcessDisableSchemaExamples(bool disableSchemaExamples) return true; } + private bool ProcessUseHttpPutForUpdate(bool useHttpPutForUpdate) + { + if (UseHttpPutForUpdate != null) + { + Console.WriteLine("[Error:] Multiple [--useputforupdate|-put] are not allowed.\n"); + PrintUsage(); + return false; + } + + UseHttpPutForUpdate = useHttpPutForUpdate; + return true; + } + private bool ProcessTarget(int version) { if (Version != null) @@ -484,6 +515,7 @@ public static void PrintUsage() sb.Append(" --enablepagination|-p\t\t\tSet the output to expose pagination for collections.\n"); sb.Append(" --enableunqualifiedcall|-u\t\t\tSet the output to use unqualified calls for bound operations.\n"); sb.Append(" --disableschemaexamples|-x\t\t\tDisable examples in the schema.\n"); + sb.Append(" --useputforupdate|-put\t\t\tUse HTTP PUT method for update operations instead of PATCH by default.\n"); sb.Append(" --json|-j\t\t\tSet the output format as JSON.\n"); sb.Append(" --yaml|-y\t\t\tSet the output format as YAML.\n"); sb.Append(" --specversion|-s IntVersion\tSet the OpenApi Specification version of the output. Only 2 or 3 are supported.\n"); diff --git a/src/OoasUtil/Program.cs b/src/OoasUtil/Program.cs index 211dc0f5..937abdde 100644 --- a/src/OoasUtil/Program.cs +++ b/src/OoasUtil/Program.cs @@ -42,6 +42,7 @@ static async System.Threading.Tasks.Task Main(string[] args) EnableUnqualifiedCall = processor.EnableUnqualifiedCall.Value, ShowSchemaExamples = !processor.DisableSchemaExamples.Value, OpenApiSpecVersion = processor.Version.Value, + UseHttpPutForUpdate = processor.UseHttpPutForUpdate.Value, }; if (processor.IsLocalFile) From 326f9511d2744d0abaf4147070524b9c250dbf46 Mon Sep 17 00:00:00 2001 From: "Gavin Barron (from Dev Box)" Date: Fri, 9 Jan 2026 12:41:19 -0800 Subject: [PATCH 2/2] fix version time-bomb --- tool/versioning.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tool/versioning.props b/tool/versioning.props index b6bd275b..5caaa033 100644 --- a/tool/versioning.props +++ b/tool/versioning.props @@ -29,7 +29,7 @@ overflows the Int16. The system convert below will throw errors when this happens. --> - 2020 + 2026 $([System.Convert]::ToInt32('$([MSBuild]::Add(1, $([MSBuild]::Subtract($([System.DateTime]::Now.Year), $(VersionStartYear)))))$([System.DateTime]::Now.ToString("MMdd"))'))