From 91e62f27a74a1884d1767a55241275cf148004bf Mon Sep 17 00:00:00 2001 From: Fabian Buchenberger <37747351+ffabss@users.noreply.github.com> Date: Tue, 25 Feb 2025 23:03:16 +0100 Subject: [PATCH] [csharp] do not use deprecated HttpRequestMessage.Properties --- .../libraries/httpclient/ApiClient.mustache | 17 +++++++- .../libraries/httpclient/ApiClient.mustache | 39 +++++++++++++------ .../src/Org.OpenAPITools/Client/ApiClient.cs | 30 +++++++------- .../src/Org.OpenAPITools/Client/ApiClient.cs | 24 ++++++------ 4 files changed, 72 insertions(+), 38 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/csharp-functions/libraries/httpclient/ApiClient.mustache b/modules/openapi-generator/src/main/resources/csharp-functions/libraries/httpclient/ApiClient.mustache index 17e260a8139f..15dcb88a0160 100644 --- a/modules/openapi-generator/src/main/resources/csharp-functions/libraries/httpclient/ApiClient.mustache +++ b/modules/openapi-generator/src/main/resources/csharp-functions/libraries/httpclient/ApiClient.mustache @@ -167,6 +167,9 @@ namespace {{packageName}}.Client /// {{>visibility}} partial class ApiClient : IDisposable, ISynchronousClient{{#supportsAsync}}, IAsynchronousClient{{/supportsAsync}} { + {{#net60OrLater}} + private static readonly HttpRequestOptionsKey> _httpOptionsCookieContainerKey = new("CookieContainer"); + {{/net60OrLater}} private readonly string _baseUrl; private readonly HttpClientHandler _httpClientHandler; @@ -382,12 +385,15 @@ namespace {{packageName}}.Client } } - - // TODO provide an alternative that allows cookies per request instead of per API client if (options.Cookies != null && options.Cookies.Count > 0) { + {{#net60OrLater}} + request.Options.Set(_httpOptionsCookieContainerKey, options.Cookies); + {{/net60OrLater}} + {{^net60OrLater}} request.Properties["CookieContainer"] = options.Cookies; + {{/net60OrLater}} } return request; @@ -474,9 +480,16 @@ namespace {{packageName}}.Client _httpClientHandler.ClientCertificates.AddRange(configuration.ClientCertificates); } + {{^net60OrLater}} var cookieContainer = req.Properties.ContainsKey("CookieContainer") ? req.Properties["CookieContainer"] as List : null; + {{/net60OrLater}} + {{#net60OrLater}} + if (req.Options.TryGetValue(_httpOptionsCookieContainerKey, out var cookieContainer)) + {{/net60OrLater}} + {{^net60OrLater}} if (cookieContainer != null) + {{/net60OrLater}} { if(_httpClientHandler == null) throw new InvalidOperationException("Request property `CookieContainer` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor."); foreach (var cookie in cookieContainer) diff --git a/modules/openapi-generator/src/main/resources/csharp/libraries/httpclient/ApiClient.mustache b/modules/openapi-generator/src/main/resources/csharp/libraries/httpclient/ApiClient.mustache index 603284acbf33..9ffa7a9318b5 100644 --- a/modules/openapi-generator/src/main/resources/csharp/libraries/httpclient/ApiClient.mustache +++ b/modules/openapi-generator/src/main/resources/csharp/libraries/httpclient/ApiClient.mustache @@ -79,7 +79,7 @@ namespace {{packageName}}.Client public async Task Deserialize(HttpResponseMessage response) { - var result = (T) await Deserialize(response, typeof(T)).ConfigureAwait(false); + var result = (T)await Deserialize(response, typeof(T)).ConfigureAwait(false); return result; } @@ -95,13 +95,13 @@ namespace {{packageName}}.Client // process response headers, e.g. Access-Control-Allow-Methods foreach (var responseHeader in response.Headers) { - headers.Add(responseHeader.Key + "=" + ClientUtils.ParameterToString(responseHeader.Value)); + headers.Add(responseHeader.Key + "=" + ClientUtils.ParameterToString(responseHeader.Value)); } // process response content headers, e.g. Content-Type foreach (var responseHeader in response.Content.Headers) { - headers.Add(responseHeader.Key + "=" + ClientUtils.ParameterToString(responseHeader.Value)); + headers.Add(responseHeader.Key + "=" + ClientUtils.ParameterToString(responseHeader.Value)); } // RFC 2183 & RFC 2616 @@ -112,7 +112,8 @@ namespace {{packageName}}.Client } else if (type == typeof(FileParameter)) { - if (headers != null) { + if (headers != null) + { foreach (var header in headers) { var match = fileNameRegex.Match(header.ToString()); @@ -191,6 +192,9 @@ namespace {{packageName}}.Client /// {{>visibility}} partial class ApiClient : IDisposable, ISynchronousClient{{#supportsAsync}}, IAsynchronousClient{{/supportsAsync}} { + {{#net60OrLater}} + private static readonly HttpRequestOptionsKey> _httpOptionsCookieContainerKey = new("CookieContainer"); + {{/net60OrLater}} private readonly string _baseUrl; private readonly HttpClientHandler _httpClientHandler; @@ -283,7 +287,8 @@ namespace {{packageName}}.Client /// public void Dispose() { - if(_disposeClient) { + if(_disposeClient) + { _httpClient.Dispose(); } } @@ -413,7 +418,12 @@ namespace {{packageName}}.Client // TODO provide an alternative that allows cookies per request instead of per API client if (options.Cookies != null && options.Cookies.Count > 0) { + {{#net60OrLater}} + request.Options.Set(_httpOptionsCookieContainerKey, options.Cookies); + {{/net60OrLater}} + {{^net60OrLater}} request.Properties["CookieContainer"] = options.Cookies; + {{/net60OrLater}} } return request; @@ -424,7 +434,7 @@ namespace {{packageName}}.Client private async Task> ToApiResponse(HttpResponseMessage response, object responseData, Uri uri) { - T result = (T) responseData; + T result = (T)responseData; string rawContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); var transformed = new ApiResponse(response.StatusCode, new Multimap({{#caseInsensitiveResponseHeaders}}StringComparer.OrdinalIgnoreCase{{/caseInsensitiveResponseHeaders}}), result, rawContent) @@ -459,7 +469,7 @@ namespace {{packageName}}.Client transformed.Cookies.Add(cookie); } } - catch (PlatformNotSupportedException) {} + catch (PlatformNotSupportedException) { } } return transformed; @@ -496,15 +506,22 @@ namespace {{packageName}}.Client if (configuration.ClientCertificates != null) { - if(_httpClientHandler == null) throw new InvalidOperationException("Configuration `ClientCertificates` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor."); + if (_httpClientHandler == null) throw new InvalidOperationException("Configuration `ClientCertificates` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor."); _httpClientHandler.ClientCertificates.AddRange(configuration.ClientCertificates); } + {{^net60OrLater}} var cookieContainer = req.Properties.ContainsKey("CookieContainer") ? req.Properties["CookieContainer"] as List : null; + {{/net60OrLater}} + {{#net60OrLater}} + if (req.Options.TryGetValue(_httpOptionsCookieContainerKey, out var cookieContainer)) + {{/net60OrLater}} + {{^net60OrLater}} if (cookieContainer != null) + {{/net60OrLater}} { - if(_httpClientHandler == null) throw new InvalidOperationException("Request property `CookieContainer` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor."); + if (_httpClientHandler == null) throw new InvalidOperationException("Request property `CookieContainer` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor."); foreach (var cookie in cookieContainer) { _httpClientHandler.CookieContainer.Add(cookie); @@ -546,11 +563,11 @@ namespace {{packageName}}.Client // if the response type is oneOf/anyOf, call FromJSON to deserialize the data if (typeof({{{packageName}}}.{{modelPackage}}.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) { - responseData = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + responseData = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); } else if (typeof(T).Name == "Stream") // for binary response { - responseData = (T) (object) await response.Content.ReadAsStreamAsync().ConfigureAwait(false); + responseData = (T)(object) await response.Content.ReadAsStreamAsync().ConfigureAwait(false); } InterceptResponse(req, response); diff --git a/samples/client/petstore/csharp/httpclient/net9/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs b/samples/client/petstore/csharp/httpclient/net9/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs index 1596e7e1f53a..2cf36b546aae 100644 --- a/samples/client/petstore/csharp/httpclient/net9/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs +++ b/samples/client/petstore/csharp/httpclient/net9/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs @@ -83,7 +83,7 @@ public string Serialize(object obj) public async Task Deserialize(HttpResponseMessage response) { - var result = (T) await Deserialize(response, typeof(T)).ConfigureAwait(false); + var result = (T)await Deserialize(response, typeof(T)).ConfigureAwait(false); return result; } @@ -99,13 +99,13 @@ internal async Task Deserialize(HttpResponseMessage response, Type type) // process response headers, e.g. Access-Control-Allow-Methods foreach (var responseHeader in response.Headers) { - headers.Add(responseHeader.Key + "=" + ClientUtils.ParameterToString(responseHeader.Value)); + headers.Add(responseHeader.Key + "=" + ClientUtils.ParameterToString(responseHeader.Value)); } // process response content headers, e.g. Content-Type foreach (var responseHeader in response.Content.Headers) { - headers.Add(responseHeader.Key + "=" + ClientUtils.ParameterToString(responseHeader.Value)); + headers.Add(responseHeader.Key + "=" + ClientUtils.ParameterToString(responseHeader.Value)); } // RFC 2183 & RFC 2616 @@ -116,7 +116,8 @@ internal async Task Deserialize(HttpResponseMessage response, Type type) } else if (type == typeof(FileParameter)) { - if (headers != null) { + if (headers != null) + { foreach (var header in headers) { var match = fileNameRegex.Match(header.ToString()); @@ -195,6 +196,7 @@ public string ContentType /// public partial class ApiClient : IDisposable, ISynchronousClient, IAsynchronousClient { + private static readonly HttpRequestOptionsKey> _httpOptionsCookieContainerKey = new("CookieContainer"); private readonly string _baseUrl; private readonly HttpClientHandler _httpClientHandler; @@ -287,7 +289,8 @@ public ApiClient(HttpClient client, string basePath, HttpClientHandler handler = /// public void Dispose() { - if(_disposeClient) { + if(_disposeClient) + { _httpClient.Dispose(); } } @@ -415,7 +418,7 @@ private HttpRequestMessage NewRequest( // TODO provide an alternative that allows cookies per request instead of per API client if (options.Cookies != null && options.Cookies.Count > 0) { - request.Properties["CookieContainer"] = options.Cookies; + request.Options.Set(_httpOptionsCookieContainerKey, options.Cookies); } return request; @@ -426,7 +429,7 @@ private HttpRequestMessage NewRequest( private async Task> ToApiResponse(HttpResponseMessage response, object responseData, Uri uri) { - T result = (T) responseData; + T result = (T)responseData; string rawContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); var transformed = new ApiResponse(response.StatusCode, new Multimap(), result, rawContent) @@ -461,7 +464,7 @@ private async Task> ToApiResponse(HttpResponseMessage response transformed.Cookies.Add(cookie); } } - catch (PlatformNotSupportedException) {} + catch (PlatformNotSupportedException) { } } return transformed; @@ -498,15 +501,14 @@ private async Task> ExecAsync(HttpRequestMessage req, if (configuration.ClientCertificates != null) { - if(_httpClientHandler == null) throw new InvalidOperationException("Configuration `ClientCertificates` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor."); + if (_httpClientHandler == null) throw new InvalidOperationException("Configuration `ClientCertificates` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor."); _httpClientHandler.ClientCertificates.AddRange(configuration.ClientCertificates); } - var cookieContainer = req.Properties.ContainsKey("CookieContainer") ? req.Properties["CookieContainer"] as List : null; - if (cookieContainer != null) + if (req.Options.TryGetValue(_httpOptionsCookieContainerKey, out var cookieContainer)) { - if(_httpClientHandler == null) throw new InvalidOperationException("Request property `CookieContainer` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor."); + if (_httpClientHandler == null) throw new InvalidOperationException("Request property `CookieContainer` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor."); foreach (var cookie in cookieContainer) { _httpClientHandler.CookieContainer.Add(cookie); @@ -544,11 +546,11 @@ private async Task> ExecAsync(HttpRequestMessage req, // if the response type is oneOf/anyOf, call FromJSON to deserialize the data if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) { - responseData = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + responseData = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); } else if (typeof(T).Name == "Stream") // for binary response { - responseData = (T) (object) await response.Content.ReadAsStreamAsync().ConfigureAwait(false); + responseData = (T)(object) await response.Content.ReadAsStreamAsync().ConfigureAwait(false); } InterceptResponse(req, response); diff --git a/samples/client/petstore/csharp/httpclient/standard2.0/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs b/samples/client/petstore/csharp/httpclient/standard2.0/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs index e6e2e5519c9b..a36c8bb3ea85 100644 --- a/samples/client/petstore/csharp/httpclient/standard2.0/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs +++ b/samples/client/petstore/csharp/httpclient/standard2.0/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs @@ -82,7 +82,7 @@ public string Serialize(object obj) public async Task Deserialize(HttpResponseMessage response) { - var result = (T) await Deserialize(response, typeof(T)).ConfigureAwait(false); + var result = (T)await Deserialize(response, typeof(T)).ConfigureAwait(false); return result; } @@ -98,13 +98,13 @@ internal async Task Deserialize(HttpResponseMessage response, Type type) // process response headers, e.g. Access-Control-Allow-Methods foreach (var responseHeader in response.Headers) { - headers.Add(responseHeader.Key + "=" + ClientUtils.ParameterToString(responseHeader.Value)); + headers.Add(responseHeader.Key + "=" + ClientUtils.ParameterToString(responseHeader.Value)); } // process response content headers, e.g. Content-Type foreach (var responseHeader in response.Content.Headers) { - headers.Add(responseHeader.Key + "=" + ClientUtils.ParameterToString(responseHeader.Value)); + headers.Add(responseHeader.Key + "=" + ClientUtils.ParameterToString(responseHeader.Value)); } // RFC 2183 & RFC 2616 @@ -115,7 +115,8 @@ internal async Task Deserialize(HttpResponseMessage response, Type type) } else if (type == typeof(FileParameter)) { - if (headers != null) { + if (headers != null) + { foreach (var header in headers) { var match = fileNameRegex.Match(header.ToString()); @@ -286,7 +287,8 @@ public ApiClient(HttpClient client, string basePath, HttpClientHandler handler = /// public void Dispose() { - if(_disposeClient) { + if(_disposeClient) + { _httpClient.Dispose(); } } @@ -425,7 +427,7 @@ private HttpRequestMessage NewRequest( private async Task> ToApiResponse(HttpResponseMessage response, object responseData, Uri uri) { - T result = (T) responseData; + T result = (T)responseData; string rawContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); var transformed = new ApiResponse(response.StatusCode, new Multimap(), result, rawContent) @@ -460,7 +462,7 @@ private async Task> ToApiResponse(HttpResponseMessage response transformed.Cookies.Add(cookie); } } - catch (PlatformNotSupportedException) {} + catch (PlatformNotSupportedException) { } } return transformed; @@ -497,7 +499,7 @@ private async Task> ExecAsync(HttpRequestMessage req, if (configuration.ClientCertificates != null) { - if(_httpClientHandler == null) throw new InvalidOperationException("Configuration `ClientCertificates` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor."); + if (_httpClientHandler == null) throw new InvalidOperationException("Configuration `ClientCertificates` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor."); _httpClientHandler.ClientCertificates.AddRange(configuration.ClientCertificates); } @@ -505,7 +507,7 @@ private async Task> ExecAsync(HttpRequestMessage req, if (cookieContainer != null) { - if(_httpClientHandler == null) throw new InvalidOperationException("Request property `CookieContainer` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor."); + if (_httpClientHandler == null) throw new InvalidOperationException("Request property `CookieContainer` not supported when the client is explicitly created without an HttpClientHandler, use the proper constructor."); foreach (var cookie in cookieContainer) { _httpClientHandler.CookieContainer.Add(cookie); @@ -543,11 +545,11 @@ private async Task> ExecAsync(HttpRequestMessage req, // if the response type is oneOf/anyOf, call FromJSON to deserialize the data if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) { - responseData = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + responseData = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); } else if (typeof(T).Name == "Stream") // for binary response { - responseData = (T) (object) await response.Content.ReadAsStreamAsync().ConfigureAwait(false); + responseData = (T)(object) await response.Content.ReadAsStreamAsync().ConfigureAwait(false); } InterceptResponse(req, response);