From e86dbf48315f45894f1a23aae29ca4a5052548c6 Mon Sep 17 00:00:00 2001 From: Marcin Szopa Date: Fri, 9 Oct 2026 19:54:15 +0200 Subject: [PATCH 1/2] [csharp][restsharp][httpclient] Keep every accepted content type in the Accept header SelectHeaderAccept collapsed the Accept header to "application/json" whenever JSON was among the candidates, dropping the operation's other response types. Operations whose primary response is binary (or any non-JSON type) and only use JSON for error responses then advertise an Accept the server cannot honour for the success path. Send all accepted types, JSON ones first so servers that honour Accept order still answer with the body the JSON codec can parse. Co-authored-by: CLIN --- .../resources/csharp/ClientUtils.mustache | 8 ++----- .../CSharpClientCodegenTest.java | 24 +++++++++++++++++++ .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- .../Org.OpenAPITools/Client/ClientUtils.cs | 8 ++----- 25 files changed, 72 insertions(+), 144 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/csharp/ClientUtils.mustache b/modules/openapi-generator/src/main/resources/csharp/ClientUtils.mustache index 4127944c4b0e..d5da856eadea 100644 --- a/modules/openapi-generator/src/main/resources/csharp/ClientUtils.mustache +++ b/modules/openapi-generator/src/main/resources/csharp/ClientUtils.mustache @@ -221,8 +221,7 @@ namespace {{packageName}}.Client /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -231,10 +230,7 @@ namespace {{packageName}}.Client if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/csharpnetcore/CSharpClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/csharpnetcore/CSharpClientCodegenTest.java index 975eb0eeb512..a68c968d5296 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/csharpnetcore/CSharpClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/csharpnetcore/CSharpClientCodegenTest.java @@ -409,6 +409,30 @@ public void testUserAgentIsNotUrlEncoded() throws IOException { } } + @Test + public void testSelectHeaderAcceptKeepsAllTypesJsonFirst() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/petstore.yaml"); + final DefaultGenerator defaultGenerator = new DefaultGenerator(); + final ClientOptInput clientOptInput = new ClientOptInput(); + clientOptInput.openAPI(openAPI); + CSharpClientCodegen cSharpClientCodegen = new CSharpClientCodegen(); + cSharpClientCodegen.setLibrary("restsharp"); + cSharpClientCodegen.setOutputDir(output.getAbsolutePath()); + clientOptInput.config(cSharpClientCodegen); + defaultGenerator.opts(clientOptInput); + + Map files = defaultGenerator.generate().stream() + .collect(Collectors.toMap(File::getPath, Function.identity())); + + File clientUtils = files + .get(Paths.get(output.getAbsolutePath(), "src", "Org.OpenAPITools", "Client", "ClientUtils.cs").toString()); + assertNotNull(clientUtils); + assertFileContains(clientUtils.toPath(), "accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)"); + assertFileNotContains(clientUtils.toPath(), "return \"application/json\";"); + } + @Test public void test31specAdditionalPropertiesOfOneOf() throws IOException { // for https://github.com/OpenAPITools/openapi-generator/pull/18772 diff --git a/samples/client/echo_api/csharp/restsharp/net8/EchoApi/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/echo_api/csharp/restsharp/net8/EchoApi/src/Org.OpenAPITools/Client/ClientUtils.cs index e3787b1a8311..5de0630accfe 100644 --- a/samples/client/echo_api/csharp/restsharp/net8/EchoApi/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/echo_api/csharp/restsharp/net8/EchoApi/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -206,8 +206,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -216,10 +215,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/others/csharp-complex-files/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/others/csharp-complex-files/src/Org.OpenAPITools/Client/ClientUtils.cs index d4d76fa0662c..d83b1e73aa81 100644 --- a/samples/client/others/csharp-complex-files/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/others/csharp-complex-files/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -215,8 +215,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -225,10 +224,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/httpclient/net10/Petstore-nonPublicApi/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/httpclient/net10/Petstore-nonPublicApi/src/Org.OpenAPITools/Client/ClientUtils.cs index 2f93eb8fd38e..509d31240250 100644 --- a/samples/client/petstore/csharp/httpclient/net10/Petstore-nonPublicApi/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/httpclient/net10/Petstore-nonPublicApi/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -221,8 +221,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -231,10 +230,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/httpclient/net10/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/httpclient/net10/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs index 5976bafe2823..32c391dc9a5f 100644 --- a/samples/client/petstore/csharp/httpclient/net10/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/httpclient/net10/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -221,8 +221,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -231,10 +230,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/httpclient/net9/Petstore-nonPublicApi/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/httpclient/net9/Petstore-nonPublicApi/src/Org.OpenAPITools/Client/ClientUtils.cs index 2f93eb8fd38e..509d31240250 100644 --- a/samples/client/petstore/csharp/httpclient/net9/Petstore-nonPublicApi/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/httpclient/net9/Petstore-nonPublicApi/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -221,8 +221,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -231,10 +230,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/httpclient/net9/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/httpclient/net9/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs index 5976bafe2823..32c391dc9a5f 100644 --- a/samples/client/petstore/csharp/httpclient/net9/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/httpclient/net9/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -221,8 +221,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -231,10 +230,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/httpclient/standard2.0/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/httpclient/standard2.0/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs index 06699bfc386b..8e47a5169216 100644 --- a/samples/client/petstore/csharp/httpclient/standard2.0/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/httpclient/standard2.0/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -215,8 +215,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -225,10 +224,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/restsharp/net10/EnumMappings/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/restsharp/net10/EnumMappings/src/Org.OpenAPITools/Client/ClientUtils.cs index 2f93eb8fd38e..509d31240250 100644 --- a/samples/client/petstore/csharp/restsharp/net10/EnumMappings/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/restsharp/net10/EnumMappings/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -221,8 +221,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -231,10 +230,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/restsharp/net10/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/restsharp/net10/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs index 5976bafe2823..32c391dc9a5f 100644 --- a/samples/client/petstore/csharp/restsharp/net10/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/restsharp/net10/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -221,8 +221,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -231,10 +230,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/restsharp/net4.7/MultipleFrameworks/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/restsharp/net4.7/MultipleFrameworks/src/Org.OpenAPITools/Client/ClientUtils.cs index 66e372d5c6d9..472b6c1ff87b 100644 --- a/samples/client/petstore/csharp/restsharp/net4.7/MultipleFrameworks/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/restsharp/net4.7/MultipleFrameworks/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -215,8 +215,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -225,10 +224,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/restsharp/net4.7/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/restsharp/net4.7/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs index 06699bfc386b..8e47a5169216 100644 --- a/samples/client/petstore/csharp/restsharp/net4.7/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/restsharp/net4.7/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -215,8 +215,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -225,10 +224,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/restsharp/net4.8/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/restsharp/net4.8/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs index 06699bfc386b..8e47a5169216 100644 --- a/samples/client/petstore/csharp/restsharp/net4.8/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/restsharp/net4.8/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -215,8 +215,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -225,10 +224,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/restsharp/net8/EnumMappings/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/restsharp/net8/EnumMappings/src/Org.OpenAPITools/Client/ClientUtils.cs index 5976bafe2823..32c391dc9a5f 100644 --- a/samples/client/petstore/csharp/restsharp/net8/EnumMappings/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/restsharp/net8/EnumMappings/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -221,8 +221,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -231,10 +230,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/restsharp/net8/ParameterMappings/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/restsharp/net8/ParameterMappings/src/Org.OpenAPITools/Client/ClientUtils.cs index 7fa3d4709d28..8ad60804ffe9 100644 --- a/samples/client/petstore/csharp/restsharp/net8/ParameterMappings/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/restsharp/net8/ParameterMappings/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -205,8 +205,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -215,10 +214,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/restsharp/net8/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/restsharp/net8/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs index 5976bafe2823..32c391dc9a5f 100644 --- a/samples/client/petstore/csharp/restsharp/net8/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/restsharp/net8/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -221,8 +221,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -231,10 +230,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/restsharp/net8/UseDateTimeForDate/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/restsharp/net8/UseDateTimeForDate/src/Org.OpenAPITools/Client/ClientUtils.cs index 27c78cc269c8..a642a2750b42 100644 --- a/samples/client/petstore/csharp/restsharp/net8/UseDateTimeForDate/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/restsharp/net8/UseDateTimeForDate/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -205,8 +205,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -215,10 +214,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/restsharp/net8/useVirtualForHooks/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/restsharp/net8/useVirtualForHooks/src/Org.OpenAPITools/Client/ClientUtils.cs index 02232ccae29f..238486a59320 100644 --- a/samples/client/petstore/csharp/restsharp/net8/useVirtualForHooks/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/restsharp/net8/useVirtualForHooks/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -205,8 +205,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -215,10 +214,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/restsharp/net9/EnumMappings/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/restsharp/net9/EnumMappings/src/Org.OpenAPITools/Client/ClientUtils.cs index 5976bafe2823..32c391dc9a5f 100644 --- a/samples/client/petstore/csharp/restsharp/net9/EnumMappings/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/restsharp/net9/EnumMappings/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -221,8 +221,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -231,10 +230,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/restsharp/standard2.0/ConditionalSerialization/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/restsharp/standard2.0/ConditionalSerialization/src/Org.OpenAPITools/Client/ClientUtils.cs index 06699bfc386b..8e47a5169216 100644 --- a/samples/client/petstore/csharp/restsharp/standard2.0/ConditionalSerialization/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/restsharp/standard2.0/ConditionalSerialization/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -215,8 +215,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -225,10 +224,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/restsharp/standard2.0/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/restsharp/standard2.0/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs index 06699bfc386b..8e47a5169216 100644 --- a/samples/client/petstore/csharp/restsharp/standard2.0/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/restsharp/standard2.0/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -215,8 +215,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -225,10 +224,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/unityWebRequest/net10/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/unityWebRequest/net10/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs index e4b650c9de82..a806c32691bf 100644 --- a/samples/client/petstore/csharp/unityWebRequest/net10/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/unityWebRequest/net10/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -205,8 +205,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -215,10 +214,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/unityWebRequest/net9/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/unityWebRequest/net9/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs index e4b650c9de82..a806c32691bf 100644 --- a/samples/client/petstore/csharp/unityWebRequest/net9/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/unityWebRequest/net9/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -205,8 +205,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -215,10 +214,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// diff --git a/samples/client/petstore/csharp/unityWebRequest/standard2.0/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs b/samples/client/petstore/csharp/unityWebRequest/standard2.0/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs index 5d6275437696..fdb55b0718e3 100644 --- a/samples/client/petstore/csharp/unityWebRequest/standard2.0/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs +++ b/samples/client/petstore/csharp/unityWebRequest/standard2.0/Petstore/src/Org.OpenAPITools/Client/ClientUtils.cs @@ -199,8 +199,7 @@ public static string SelectHeaderContentType(string[] contentTypes) /// /// Select the Accept header's value from the given accepts array: - /// if JSON exists in the given array, use it; - /// otherwise use all of them (joining into a string) + /// all of them, JSON types first (joining into a string) /// /// The accepts array to select from. /// The Accept header to use. @@ -209,10 +208,7 @@ public static string SelectHeaderAccept(string[] accepts) if (accepts.Length == 0) return null; - if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) - return "application/json"; - - return string.Join(",", accepts); + return string.Join(",", accepts.OrderBy(accept => IsJsonMime(accept) ? 0 : 1)); } /// From 89c85ac8ec4f64123a2b5096b6c7d8ead8474327 Mon Sep 17 00:00:00 2001 From: Marcin Szopa Date: Tue, 13 Oct 2026 11:11:12 +0200 Subject: [PATCH 2/2] [csharp][restsharp] Add Accept header test to the MultipleFrameworks sample An operation that produces both XML and JSON must send both types, JSON first. Fails against the previous SelectHeaderAccept, which sent only application/json. Co-authored-by: CLIN --- .../Client/AcceptHeaderTests.cs | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 samples/client/petstore/csharp/restsharp/net4.7/MultipleFrameworks/src/Org.OpenAPITools.Test/Client/AcceptHeaderTests.cs diff --git a/samples/client/petstore/csharp/restsharp/net4.7/MultipleFrameworks/src/Org.OpenAPITools.Test/Client/AcceptHeaderTests.cs b/samples/client/petstore/csharp/restsharp/net4.7/MultipleFrameworks/src/Org.OpenAPITools.Test/Client/AcceptHeaderTests.cs new file mode 100644 index 000000000000..e180c7ca246b --- /dev/null +++ b/samples/client/petstore/csharp/restsharp/net4.7/MultipleFrameworks/src/Org.OpenAPITools.Test/Client/AcceptHeaderTests.cs @@ -0,0 +1,46 @@ +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; +using Org.OpenAPITools.Api; +using Xunit; + +namespace Org.OpenAPITools.Test.Client +{ + public sealed class AcceptHeaderTests + { + [Fact] + public void MixedResponseTypes_SendsAllAcceptTypesJsonFirst() + { + var port = FreePort(); + using (var server = new HttpListener()) + { + server.Prefixes.Add("http://127.0.0.1:" + port + "/"); + server.Start(); + var accept = Task.Run(() => + { + var ctx = server.GetContext(); + var sent = ctx.Request.Headers["Accept"]; + var body = Encoding.UTF8.GetBytes("{\"name\":\"doggie\",\"photoUrls\":[]}"); + ctx.Response.ContentType = "application/json"; + ctx.Response.OutputStream.Write(body, 0, body.Length); + ctx.Response.Close(); + return sent; + }); + + new PetApi("http://127.0.0.1:" + port).GetPetById(1); + + Assert.Equal("application/json,application/xml", accept.Result); + } + } + + private static int FreePort() + { + var listener = new TcpListener(IPAddress.Loopback, 0); + listener.Start(); + var port = ((IPEndPoint)listener.LocalEndpoint).Port; + listener.Stop(); + return port; + } + } +}