diff --git a/docs/tutorials/GenerateProxyClientWithCLI/generate-proxy-client.md b/docs/tutorials/GenerateProxyClientWithCLI/generate-proxy-client.md index de1e8b58e..c5b5334db 100644 --- a/docs/tutorials/GenerateProxyClientWithCLI/generate-proxy-client.md +++ b/docs/tutorials/GenerateProxyClientWithCLI/generate-proxy-client.md @@ -107,6 +107,7 @@ nswag run sample.nswag /runtime:Net50 "operationGenerationMode": "MultipleClientsFromOperationId", "includedOperationIds": [ "SampleOperationId" ], "excludedOperationIds": [], + "excludeDeprecated": false, "generateOptionalParameters": false, "generateJsonMethods": true, "parameterArrayType": "System.Collections.Generic.IEnumerable", diff --git a/docs/tutorials/GenerateProxyClientWithCLI/sample.nswag b/docs/tutorials/GenerateProxyClientWithCLI/sample.nswag index 796d9b58c..58a283949 100644 Binary files a/docs/tutorials/GenerateProxyClientWithCLI/sample.nswag and b/docs/tutorials/GenerateProxyClientWithCLI/sample.nswag differ diff --git a/src/NSwag.ApiDescription.Client/NSwag.ApiDescription.Client.props b/src/NSwag.ApiDescription.Client/NSwag.ApiDescription.Client.props index b5e000249..0fe1b28d0 100644 --- a/src/NSwag.ApiDescription.Client/NSwag.ApiDescription.Client.props +++ b/src/NSwag.ApiDescription.Client/NSwag.ApiDescription.Client.props @@ -130,6 +130,7 @@ $(NSwagOperationGenerationMode) $(NSwagIncludedOperationIds) $(NSwagExcludedOperationIds) + $(NSwagExcludeDeprecated) $(NSwagAdditionalNamespaceUsages) $(NSwagAdditionalContractNamespaceUsages) $(NSwagGenerateOptionalParameters) diff --git a/src/NSwag.ApiDescription.Client/NSwag.ApiDescription.Client.targets b/src/NSwag.ApiDescription.Client/NSwag.ApiDescription.Client.targets index a40585721..213877785 100644 --- a/src/NSwag.ApiDescription.Client/NSwag.ApiDescription.Client.targets +++ b/src/NSwag.ApiDescription.Client/NSwag.ApiDescription.Client.targets @@ -127,6 +127,9 @@ %(Command) /excludedOperationIds:%(NSwagExcludedOperationIds) + + %(Command) /excludeDeprecated:%(NSwagExcludeDeprecated) + %(Command) /additionalNamespaceUsages:%(NSwagAdditionalNamespaceUsages) diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/CSharpClientSettingsTests.cs b/src/NSwag.CodeGeneration.CSharp.Tests/CSharpClientSettingsTests.cs index 0fa6f3675..bf07bda9d 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/CSharpClientSettingsTests.cs +++ b/src/NSwag.CodeGeneration.CSharp.Tests/CSharpClientSettingsTests.cs @@ -20,6 +20,9 @@ public object CreatePerson(bool @override = false) return null; } +#pragma warning disable S1133 // Deprecated code should be removed + [Obsolete("Testing generation of obsolete endpoints")] +#pragma warning restore S1133 // Deprecated code should be removed public object DeletePerson(bool @override = false) { return null; @@ -413,5 +416,58 @@ await VerifyHelper.Verify(code) .UseParameters(excludedOperationIds.Length); CSharpCompiler.AssertCompile(code); } + + [Fact] + public async Task When_depreacted_endpoints_are_excluded_the_client_should_not_generate_these_endpoint() + { + // Arrange + var swaggerGenerator = new WebApiOpenApiDocumentGenerator(new WebApiOpenApiDocumentGeneratorSettings + { + SchemaSettings = new NewtonsoftJsonSchemaGeneratorSettings() + }); + + var document = await swaggerGenerator.GenerateForControllerAsync(); + var generator = new CSharpClientGenerator(document, new CSharpClientGeneratorSettings + { + GenerateClientClasses = true, + ExcludeDeprecated = true + }); + + // Act + var code = generator.GenerateFile(); + + // Assert + Assert.DoesNotContain("DeletePerson", code); + Assert.DoesNotContain("Obsolete", code); + await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code); + } + + [Fact] + public async Task When_depreacted_endpoints_are_excluded_the_client_should_still_generate_explicitly_included_endpoints() + { + // Arrange + var swaggerGenerator = new WebApiOpenApiDocumentGenerator(new WebApiOpenApiDocumentGeneratorSettings + { + SchemaSettings = new NewtonsoftJsonSchemaGeneratorSettings() + }); + + var document = await swaggerGenerator.GenerateForControllerAsync(); + var generator = new CSharpClientGenerator(document, new CSharpClientGeneratorSettings + { + GenerateClientClasses = true, + ExcludeDeprecated = true, + IncludedOperationIds = ["Foo_DeletePerson"] + }); + + // Act + var code = generator.GenerateFile(); + + // Assert + Assert.Contains("DeletePerson", code); + Assert.Contains("Obsolete", code); + await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code); + } } } \ No newline at end of file diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.WhenUsingBaseUrl_ButNoProperty_ThenPropertyIsNotUsedAndFieldIsGenerated.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.WhenUsingBaseUrl_ButNoProperty_ThenPropertyIsNotUsedAndFieldIsGenerated.verified.txt index 727b7f20e..b2bdee072 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.WhenUsingBaseUrl_ButNoProperty_ThenPropertyIsNotUsedAndFieldIsGenerated.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.WhenUsingBaseUrl_ButNoProperty_ThenPropertyIsNotUsedAndFieldIsGenerated.verified.txt @@ -193,11 +193,13 @@ namespace MyNamespace } } + [System.Obsolete] public virtual System.Threading.Tasks.Task DeletePersonAsync(bool? @override) { return DeletePersonAsync(@override, System.Threading.CancellationToken.None); } + [System.Obsolete] public virtual async System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken) { var client_ = _httpClient; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_ConfigurationClass_is_set_then_correct_ctor_is_generated.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_ConfigurationClass_is_set_then_correct_ctor_is_generated.verified.txt index 55b8132bb..1a17fb2cc 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_ConfigurationClass_is_set_then_correct_ctor_is_generated.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_ConfigurationClass_is_set_then_correct_ctor_is_generated.verified.txt @@ -200,11 +200,13 @@ namespace MyNamespace } } + [System.Obsolete] public virtual System.Threading.Tasks.Task DeletePersonAsync(bool? @override) { return DeletePersonAsync(@override, System.Threading.CancellationToken.None); } + [System.Obsolete] public virtual async System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken) { var client_ = new System.Net.Http.HttpClient(); diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_UseHttpRequestMessageCreationMethod_is_set_then_CreateRequestMessage_is_generated.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_UseHttpRequestMessageCreationMethod_is_set_then_CreateRequestMessage_is_generated.verified.txt index e743ff1ad..4a974409f 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_UseHttpRequestMessageCreationMethod_is_set_then_CreateRequestMessage_is_generated.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_UseHttpRequestMessageCreationMethod_is_set_then_CreateRequestMessage_is_generated.verified.txt @@ -202,11 +202,13 @@ namespace MyNamespace } } + [System.Obsolete] public virtual System.Threading.Tasks.Task DeletePersonAsync(bool? @override) { return DeletePersonAsync(@override, System.Threading.CancellationToken.None); } + [System.Obsolete] public virtual async System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken) { var client_ = _httpClient; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_base_interface_is_not_specified_then_client_interface_should_have_no_base_interface.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_base_interface_is_not_specified_then_client_interface_should_have_no_base_interface.verified.txt index 3d1f9946b..7fecd0e0a 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_base_interface_is_not_specified_then_client_interface_should_have_no_base_interface.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_base_interface_is_not_specified_then_client_interface_should_have_no_base_interface.verified.txt @@ -14,8 +14,10 @@ namespace MyNamespace System.Threading.Tasks.Task CreatePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken); + [System.Obsolete] System.Threading.Tasks.Task DeletePersonAsync(bool? @override); + [System.Obsolete] System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken); } @@ -218,11 +220,13 @@ namespace MyNamespace } } + [System.Obsolete] public virtual System.Threading.Tasks.Task DeletePersonAsync(bool? @override) { return DeletePersonAsync(@override, System.Threading.CancellationToken.None); } + [System.Obsolete] public virtual async System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken) { var client_ = _httpClient; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_base_interface_is_not_specified_then_client_interface_should_have_no_base_interface_and_has_correct_access_modifier.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_base_interface_is_not_specified_then_client_interface_should_have_no_base_interface_and_has_correct_access_modifier.verified.txt index 0b2c390fb..fc9a665eb 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_base_interface_is_not_specified_then_client_interface_should_have_no_base_interface_and_has_correct_access_modifier.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_base_interface_is_not_specified_then_client_interface_should_have_no_base_interface_and_has_correct_access_modifier.verified.txt @@ -14,8 +14,10 @@ namespace MyNamespace System.Threading.Tasks.Task CreatePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken); + [System.Obsolete] System.Threading.Tasks.Task DeletePersonAsync(bool? @override); + [System.Obsolete] System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken); } @@ -218,11 +220,13 @@ namespace MyNamespace } } + [System.Obsolete] public virtual System.Threading.Tasks.Task DeletePersonAsync(bool? @override) { return DeletePersonAsync(@override, System.Threading.CancellationToken.None); } + [System.Obsolete] public virtual async System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken) { var client_ = _httpClient; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_base_interface_is_specified_then_client_interface_extends_it.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_base_interface_is_specified_then_client_interface_extends_it.verified.txt index eaee6d3fb..a8ab04dc9 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_base_interface_is_specified_then_client_interface_extends_it.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_base_interface_is_specified_then_client_interface_extends_it.verified.txt @@ -14,8 +14,10 @@ namespace MyNamespace System.Threading.Tasks.Task CreatePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken); + [System.Obsolete] System.Threading.Tasks.Task DeletePersonAsync(bool? @override); + [System.Obsolete] System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken); } @@ -218,11 +220,13 @@ namespace MyNamespace } } + [System.Obsolete] public virtual System.Threading.Tasks.Task DeletePersonAsync(bool? @override) { return DeletePersonAsync(@override, System.Threading.CancellationToken.None); } + [System.Obsolete] public virtual async System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken) { var client_ = _httpClient; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_base_interface_is_specified_with_access_modifier_then_client_interface_extends_it_and_has_correct_access_modifier.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_base_interface_is_specified_with_access_modifier_then_client_interface_extends_it_and_has_correct_access_modifier.verified.txt index 220680fe3..4d6a0e042 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_base_interface_is_specified_with_access_modifier_then_client_interface_extends_it_and_has_correct_access_modifier.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_base_interface_is_specified_with_access_modifier_then_client_interface_extends_it_and_has_correct_access_modifier.verified.txt @@ -14,8 +14,10 @@ namespace MyNamespace System.Threading.Tasks.Task CreatePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken); + [System.Obsolete] System.Threading.Tasks.Task DeletePersonAsync(bool? @override); + [System.Obsolete] System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken); } @@ -218,11 +220,13 @@ namespace MyNamespace } } + [System.Obsolete] public virtual System.Threading.Tasks.Task DeletePersonAsync(bool? @override) { return DeletePersonAsync(@override, System.Threading.CancellationToken.None); } + [System.Obsolete] public virtual async System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken) { var client_ = _httpClient; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_class_generation_is_enabled_and_suppressed_then_client_class_is_not_generated.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_class_generation_is_enabled_and_suppressed_then_client_class_is_not_generated.verified.txt index 8ec1457b1..5aff58455 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_class_generation_is_enabled_and_suppressed_then_client_class_is_not_generated.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_class_generation_is_enabled_and_suppressed_then_client_class_is_not_generated.verified.txt @@ -14,8 +14,10 @@ namespace MyNamespace System.Threading.Tasks.Task CreatePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken); + [System.Obsolete] System.Threading.Tasks.Task DeletePersonAsync(bool? @override); + [System.Obsolete] System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken); } diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_interface_generation_is_enabled_and_suppressed_then_client_interface_is_not_generated.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_interface_generation_is_enabled_and_suppressed_then_client_interface_is_not_generated.verified.txt index a34477ab1..22e16d4ff 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_interface_generation_is_enabled_and_suppressed_then_client_interface_is_not_generated.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_client_interface_generation_is_enabled_and_suppressed_then_client_interface_is_not_generated.verified.txt @@ -202,11 +202,13 @@ namespace MyNamespace } } + [System.Obsolete] public virtual System.Threading.Tasks.Task DeletePersonAsync(bool? @override) { return DeletePersonAsync(@override, System.Threading.CancellationToken.None); } + [System.Obsolete] public virtual async System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken) { var client_ = _httpClient; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_code_is_generated_then_by_default_the_system_httpclient_is_used.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_code_is_generated_then_by_default_the_system_httpclient_is_used.verified.txt index 77602d812..2c32fa595 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_code_is_generated_then_by_default_the_system_httpclient_is_used.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_code_is_generated_then_by_default_the_system_httpclient_is_used.verified.txt @@ -200,11 +200,13 @@ namespace MyNamespace } } + [System.Obsolete] public virtual System.Threading.Tasks.Task DeletePersonAsync(bool? @override) { return DeletePersonAsync(@override, System.Threading.CancellationToken.None); } + [System.Obsolete] public virtual async System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken) { var client_ = new System.Net.Http.HttpClient(); diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_custom_http_client_type_is_specified_then_an_instance_of_that_type_is_used.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_custom_http_client_type_is_specified_then_an_instance_of_that_type_is_used.verified.txt index 401ed3b4f..063eecc47 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_custom_http_client_type_is_specified_then_an_instance_of_that_type_is_used.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_custom_http_client_type_is_specified_then_an_instance_of_that_type_is_used.verified.txt @@ -200,11 +200,13 @@ namespace MyNamespace } } + [System.Obsolete] public virtual System.Threading.Tasks.Task DeletePersonAsync(bool? @override) { return DeletePersonAsync(@override, System.Threading.CancellationToken.None); } + [System.Obsolete] public virtual async System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken) { var client_ = new CustomNamespace.CustomHttpClient(); diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_depreacted_endpoints_are_excluded_the_client_should_not_generate_these_endpoint.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_depreacted_endpoints_are_excluded_the_client_should_not_generate_these_endpoint.verified.txt new file mode 100644 index 000000000..a0c6118b1 --- /dev/null +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_depreacted_endpoints_are_excluded_the_client_should_not_generate_these_endpoint.verified.txt @@ -0,0 +1,374 @@ + + +namespace MyNamespace +{ + using System = global::System; + + public partial class FooClient + { + #pragma warning disable 8618 + private string _baseUrl; + #pragma warning restore 8618 + + private System.Net.Http.HttpClient _httpClient; + private static System.Lazy _settings = new System.Lazy(CreateSerializerSettings, true); + private Newtonsoft.Json.JsonSerializerSettings _instanceSettings; + + #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + public FooClient(string baseUrl, System.Net.Http.HttpClient httpClient) + #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + { + BaseUrl = baseUrl; + _httpClient = httpClient; + Initialize(); + } + + private static Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings() + { + var settings = new Newtonsoft.Json.JsonSerializerSettings(); + UpdateJsonSerializerSettings(settings); + return settings; + } + + public string BaseUrl + { + get { return _baseUrl; } + set + { + _baseUrl = value; + if (!string.IsNullOrEmpty(_baseUrl) && !_baseUrl.EndsWith("/")) + _baseUrl += '/'; + } + } + + protected Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettings { get { return _instanceSettings ?? _settings.Value; } } + + static partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings); + + partial void Initialize(); + + partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url); + partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder); + partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response); + + public virtual System.Threading.Tasks.Task GetPersonAsync(bool? @override) + { + return GetPersonAsync(@override, System.Threading.CancellationToken.None); + } + + public virtual async System.Threading.Tasks.Task GetPersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken) + { + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Method = new System.Net.Http.HttpMethod("GET"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + var urlBuilder_ = new System.Text.StringBuilder(); + if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); + // Operation Path: "api/Foo" + urlBuilder_.Append("api/Foo"); + urlBuilder_.Append('?'); + if (@override != null) + { + urlBuilder_.Append(System.Uri.EscapeDataString("override")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(@override, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } + urlBuilder_.Length--; + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = new System.Collections.Generic.Dictionary>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + return objectResponse_.Object; + } + else + { + var responseData_ = response_.Content == null ? null : await ReadAsStringAsync(response_.Content, cancellationToken).ConfigureAwait(false); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + public virtual System.Threading.Tasks.Task CreatePersonAsync(bool? @override) + { + return CreatePersonAsync(@override, System.Threading.CancellationToken.None); + } + + public virtual async System.Threading.Tasks.Task CreatePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken) + { + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Content = new System.Net.Http.StringContent(string.Empty, System.Text.Encoding.UTF8, "application/json"); + request_.Method = new System.Net.Http.HttpMethod("POST"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + var urlBuilder_ = new System.Text.StringBuilder(); + if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); + // Operation Path: "api/Foo" + urlBuilder_.Append("api/Foo"); + urlBuilder_.Append('?'); + if (@override != null) + { + urlBuilder_.Append(System.Uri.EscapeDataString("override")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(@override, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } + urlBuilder_.Length--; + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = new System.Collections.Generic.Dictionary>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + return objectResponse_.Object; + } + else + { + var responseData_ = response_.Content == null ? null : await ReadAsStringAsync(response_.Content, cancellationToken).ConfigureAwait(false); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + protected struct ObjectResponseResult + { + public ObjectResponseResult(T responseObject, string responseText) + { + this.Object = responseObject; + this.Text = responseText; + } + + public T Object { get; } + + public string Text { get; } + } + + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + private static System.Threading.Tasks.Task ReadAsStringAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) + { + #if NET5_0_OR_GREATER + return content.ReadAsStringAsync(cancellationToken); + #else + return content.ReadAsStringAsync(); + #endif + } + + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + private static System.Threading.Tasks.Task ReadAsStreamAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) + { + #if NET5_0_OR_GREATER + return content.ReadAsStreamAsync(cancellationToken); + #else + return content.ReadAsStreamAsync(); + #endif + } + + public bool ReadResponseAsString { get; set; } + + protected virtual async System.Threading.Tasks.Task> ReadObjectResponseAsync(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary> headers, System.Threading.CancellationToken cancellationToken) + { + if (response == null || response.Content == null) + { + return new ObjectResponseResult(default(T), string.Empty); + } + + if (ReadResponseAsString) + { + var responseText = await ReadAsStringAsync(response.Content, cancellationToken).ConfigureAwait(false); + try + { + var typedBody = Newtonsoft.Json.JsonConvert.DeserializeObject(responseText, JsonSerializerSettings); + return new ObjectResponseResult(typedBody, responseText); + } + catch (Newtonsoft.Json.JsonException exception) + { + var message = "Could not deserialize the response body string as " + typeof(T).FullName + "."; + throw new ApiException(message, (int)response.StatusCode, responseText, headers, exception); + } + } + else + { + try + { + using (var responseStream = await ReadAsStreamAsync(response.Content, cancellationToken).ConfigureAwait(false)) + using (var streamReader = new System.IO.StreamReader(responseStream)) + using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader)) + { + var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings); + var typedBody = serializer.Deserialize(jsonTextReader); + return new ObjectResponseResult(typedBody, string.Empty); + } + } + catch (Newtonsoft.Json.JsonException exception) + { + var message = "Could not deserialize the response body stream as " + typeof(T).FullName + "."; + throw new ApiException(message, (int)response.StatusCode, string.Empty, headers, exception); + } + } + } + + private string ConvertToString(object value, System.Globalization.CultureInfo cultureInfo) + { + if (value == null) + { + return ""; + } + + if (value is System.Enum) + { + var name = System.Enum.GetName(value.GetType(), value); + if (name != null) + { + var field_ = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name); + if (field_ != null) + { + var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field_, typeof(System.Runtime.Serialization.EnumMemberAttribute)) + as System.Runtime.Serialization.EnumMemberAttribute; + if (attribute != null) + { + return attribute.Value != null ? attribute.Value : name; + } + } + + var converted = System.Convert.ToString(System.Convert.ChangeType(value, System.Enum.GetUnderlyingType(value.GetType()), cultureInfo)); + return converted == null ? string.Empty : converted; + } + } + else if (value is bool) + { + return System.Convert.ToString((bool)value, cultureInfo).ToLowerInvariant(); + } + else if (value is byte[]) + { + return System.Convert.ToBase64String((byte[]) value); + } + else if (value is string[]) + { + return string.Join(",", (string[])value); + } + else if (value.GetType().IsArray) + { + var valueArray = (System.Array)value; + var valueTextArray = new string[valueArray.Length]; + for (var i = 0; i < valueArray.Length; i++) + { + valueTextArray[i] = ConvertToString(valueArray.GetValue(i), cultureInfo); + } + return string.Join(",", valueTextArray); + } + + var result = System.Convert.ToString(value, cultureInfo); + return result == null ? "" : result; + } + } + + + + + + public partial class ApiException : System.Exception + { + public int StatusCode { get; private set; } + + public string Response { get; private set; } + + public System.Collections.Generic.IReadOnlyDictionary> Headers { get; private set; } + + public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary> headers, System.Exception innerException) + : base(message + "\n\nStatus: " + statusCode + "\nResponse: \n" + ((response == null) ? "(null)" : response.Substring(0, response.Length >= 512 ? 512 : response.Length)), innerException) + { + StatusCode = statusCode; + Response = response; + Headers = headers; + } + + public override string ToString() + { + return string.Format("HTTP Response: \n\n{0}\n\n{1}", Response, base.ToString()); + } + } + + public partial class ApiException : ApiException + { + public TResult Result { get; private set; } + + public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary> headers, TResult result, System.Exception innerException) + : base(message, statusCode, response, headers, innerException) + { + Result = result; + } + } + +} diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_depreacted_endpoints_are_excluded_the_client_should_still_generate_explicitly_included_endpoints.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_depreacted_endpoints_are_excluded_the_client_should_still_generate_explicitly_included_endpoints.verified.txt new file mode 100644 index 000000000..1d7e5a6a9 --- /dev/null +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_depreacted_endpoints_are_excluded_the_client_should_still_generate_explicitly_included_endpoints.verified.txt @@ -0,0 +1,300 @@ + + +namespace MyNamespace +{ + using System = global::System; + + public partial class FooClient + { + #pragma warning disable 8618 + private string _baseUrl; + #pragma warning restore 8618 + + private System.Net.Http.HttpClient _httpClient; + private static System.Lazy _settings = new System.Lazy(CreateSerializerSettings, true); + private Newtonsoft.Json.JsonSerializerSettings _instanceSettings; + + #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + public FooClient(string baseUrl, System.Net.Http.HttpClient httpClient) + #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + { + BaseUrl = baseUrl; + _httpClient = httpClient; + Initialize(); + } + + private static Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings() + { + var settings = new Newtonsoft.Json.JsonSerializerSettings(); + UpdateJsonSerializerSettings(settings); + return settings; + } + + public string BaseUrl + { + get { return _baseUrl; } + set + { + _baseUrl = value; + if (!string.IsNullOrEmpty(_baseUrl) && !_baseUrl.EndsWith("/")) + _baseUrl += '/'; + } + } + + protected Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettings { get { return _instanceSettings ?? _settings.Value; } } + + static partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings); + + partial void Initialize(); + + partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url); + partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder); + partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response); + + [System.Obsolete] + public virtual System.Threading.Tasks.Task DeletePersonAsync(bool? @override) + { + return DeletePersonAsync(@override, System.Threading.CancellationToken.None); + } + + [System.Obsolete] + public virtual async System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken) + { + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Method = new System.Net.Http.HttpMethod("DELETE"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + var urlBuilder_ = new System.Text.StringBuilder(); + if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); + // Operation Path: "api/Foo" + urlBuilder_.Append("api/Foo"); + urlBuilder_.Append('?'); + if (@override != null) + { + urlBuilder_.Append(System.Uri.EscapeDataString("override")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(@override, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } + urlBuilder_.Length--; + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = new System.Collections.Generic.Dictionary>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + return objectResponse_.Object; + } + else + { + var responseData_ = response_.Content == null ? null : await ReadAsStringAsync(response_.Content, cancellationToken).ConfigureAwait(false); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + protected struct ObjectResponseResult + { + public ObjectResponseResult(T responseObject, string responseText) + { + this.Object = responseObject; + this.Text = responseText; + } + + public T Object { get; } + + public string Text { get; } + } + + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + private static System.Threading.Tasks.Task ReadAsStringAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) + { + #if NET5_0_OR_GREATER + return content.ReadAsStringAsync(cancellationToken); + #else + return content.ReadAsStringAsync(); + #endif + } + + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + private static System.Threading.Tasks.Task ReadAsStreamAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken) + { + #if NET5_0_OR_GREATER + return content.ReadAsStreamAsync(cancellationToken); + #else + return content.ReadAsStreamAsync(); + #endif + } + + public bool ReadResponseAsString { get; set; } + + protected virtual async System.Threading.Tasks.Task> ReadObjectResponseAsync(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary> headers, System.Threading.CancellationToken cancellationToken) + { + if (response == null || response.Content == null) + { + return new ObjectResponseResult(default(T), string.Empty); + } + + if (ReadResponseAsString) + { + var responseText = await ReadAsStringAsync(response.Content, cancellationToken).ConfigureAwait(false); + try + { + var typedBody = Newtonsoft.Json.JsonConvert.DeserializeObject(responseText, JsonSerializerSettings); + return new ObjectResponseResult(typedBody, responseText); + } + catch (Newtonsoft.Json.JsonException exception) + { + var message = "Could not deserialize the response body string as " + typeof(T).FullName + "."; + throw new ApiException(message, (int)response.StatusCode, responseText, headers, exception); + } + } + else + { + try + { + using (var responseStream = await ReadAsStreamAsync(response.Content, cancellationToken).ConfigureAwait(false)) + using (var streamReader = new System.IO.StreamReader(responseStream)) + using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader)) + { + var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings); + var typedBody = serializer.Deserialize(jsonTextReader); + return new ObjectResponseResult(typedBody, string.Empty); + } + } + catch (Newtonsoft.Json.JsonException exception) + { + var message = "Could not deserialize the response body stream as " + typeof(T).FullName + "."; + throw new ApiException(message, (int)response.StatusCode, string.Empty, headers, exception); + } + } + } + + private string ConvertToString(object value, System.Globalization.CultureInfo cultureInfo) + { + if (value == null) + { + return ""; + } + + if (value is System.Enum) + { + var name = System.Enum.GetName(value.GetType(), value); + if (name != null) + { + var field_ = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name); + if (field_ != null) + { + var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field_, typeof(System.Runtime.Serialization.EnumMemberAttribute)) + as System.Runtime.Serialization.EnumMemberAttribute; + if (attribute != null) + { + return attribute.Value != null ? attribute.Value : name; + } + } + + var converted = System.Convert.ToString(System.Convert.ChangeType(value, System.Enum.GetUnderlyingType(value.GetType()), cultureInfo)); + return converted == null ? string.Empty : converted; + } + } + else if (value is bool) + { + return System.Convert.ToString((bool)value, cultureInfo).ToLowerInvariant(); + } + else if (value is byte[]) + { + return System.Convert.ToBase64String((byte[]) value); + } + else if (value is string[]) + { + return string.Join(",", (string[])value); + } + else if (value.GetType().IsArray) + { + var valueArray = (System.Array)value; + var valueTextArray = new string[valueArray.Length]; + for (var i = 0; i < valueArray.Length; i++) + { + valueTextArray[i] = ConvertToString(valueArray.GetValue(i), cultureInfo); + } + return string.Join(",", valueTextArray); + } + + var result = System.Convert.ToString(value, cultureInfo); + return result == null ? "" : result; + } + } + + + + + + public partial class ApiException : System.Exception + { + public int StatusCode { get; private set; } + + public string Response { get; private set; } + + public System.Collections.Generic.IReadOnlyDictionary> Headers { get; private set; } + + public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary> headers, System.Exception innerException) + : base(message + "\n\nStatus: " + statusCode + "\nResponse: \n" + ((response == null) ? "(null)" : response.Substring(0, response.Length >= 512 ? 512 : response.Length)), innerException) + { + StatusCode = statusCode; + Response = response; + Headers = headers; + } + + public override string ToString() + { + return string.Format("HTTP Response: \n\n{0}\n\n{1}", Response, base.ToString()); + } + } + + public partial class ApiException : ApiException + { + public TResult Result { get; private set; } + + public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary> headers, TResult result, System.Exception innerException) + : base(message, statusCode, response, headers, innerException) + { + Result = result; + } + } + +} diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_exclude_operation_ids_is_provided_then_selected_operations_should_be_excluded_from_generated_code_excludedOperationIds=1.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_exclude_operation_ids_is_provided_then_selected_operations_should_be_excluded_from_generated_code_excludedOperationIds=1.verified.txt index f51917ccb..fb6e57603 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_exclude_operation_ids_is_provided_then_selected_operations_should_be_excluded_from_generated_code_excludedOperationIds=1.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_exclude_operation_ids_is_provided_then_selected_operations_should_be_excluded_from_generated_code_excludedOperationIds=1.verified.txt @@ -10,8 +10,10 @@ namespace MyNamespace System.Threading.Tasks.Task CreatePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken); + [System.Obsolete] System.Threading.Tasks.Task DeletePersonAsync(bool? @override); + [System.Obsolete] System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken); } @@ -139,11 +141,13 @@ namespace MyNamespace } } + [System.Obsolete] public virtual System.Threading.Tasks.Task DeletePersonAsync(bool? @override) { return DeletePersonAsync(@override, System.Threading.CancellationToken.None); } + [System.Obsolete] public virtual async System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken) { var client_ = _httpClient; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_exclude_operation_ids_is_provided_then_selected_operations_should_be_excluded_from_generated_code_excludedOperationIds=2.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_exclude_operation_ids_is_provided_then_selected_operations_should_be_excluded_from_generated_code_excludedOperationIds=2.verified.txt index a3b9da0dd..9010bb730 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_exclude_operation_ids_is_provided_then_selected_operations_should_be_excluded_from_generated_code_excludedOperationIds=2.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_exclude_operation_ids_is_provided_then_selected_operations_should_be_excluded_from_generated_code_excludedOperationIds=2.verified.txt @@ -6,8 +6,10 @@ namespace MyNamespace public partial interface IFooClient { + [System.Obsolete] System.Threading.Tasks.Task DeletePersonAsync(bool? @override); + [System.Obsolete] System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken); } @@ -59,11 +61,13 @@ namespace MyNamespace partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder); partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response); + [System.Obsolete] public virtual System.Threading.Tasks.Task DeletePersonAsync(bool? @override) { return DeletePersonAsync(@override, System.Threading.CancellationToken.None); } + [System.Obsolete] public virtual async System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken) { var client_ = _httpClient; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_include_operation_ids_is_provided_then_only_selected_operations_are_included_in_generated_code_includedOperationIds=3.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_include_operation_ids_is_provided_then_only_selected_operations_are_included_in_generated_code_includedOperationIds=3.verified.txt index 3d1f9946b..7fecd0e0a 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_include_operation_ids_is_provided_then_only_selected_operations_are_included_in_generated_code_includedOperationIds=3.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_include_operation_ids_is_provided_then_only_selected_operations_are_included_in_generated_code_includedOperationIds=3.verified.txt @@ -14,8 +14,10 @@ namespace MyNamespace System.Threading.Tasks.Task CreatePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken); + [System.Obsolete] System.Threading.Tasks.Task DeletePersonAsync(bool? @override); + [System.Obsolete] System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken); } @@ -218,11 +220,13 @@ namespace MyNamespace } } + [System.Obsolete] public virtual System.Threading.Tasks.Task DeletePersonAsync(bool? @override) { return DeletePersonAsync(@override, System.Threading.CancellationToken.None); } + [System.Obsolete] public virtual async System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken) { var client_ = _httpClient; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_parameter_name_is_reserved_keyword_then_it_is_appended_with_at.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_parameter_name_is_reserved_keyword_then_it_is_appended_with_at.verified.txt index fd4faf42c..6496f7ec8 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_parameter_name_is_reserved_keyword_then_it_is_appended_with_at.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/CSharpClientSettingsTests.When_parameter_name_is_reserved_keyword_then_it_is_appended_with_at.verified.txt @@ -202,11 +202,13 @@ namespace MyNamespace } } + [System.Obsolete] public virtual System.Threading.Tasks.Task DeletePersonAsync(bool? @override) { return DeletePersonAsync(@override, System.Threading.CancellationToken.None); } + [System.Obsolete] public virtual async System.Threading.Tasks.Task DeletePersonAsync(bool? @override, System.Threading.CancellationToken cancellationToken) { var client_ = _httpClient; diff --git a/src/NSwag.CodeGeneration/ClientGeneratorBase.cs b/src/NSwag.CodeGeneration/ClientGeneratorBase.cs index 84db85b18..e0dbe0022 100644 --- a/src/NSwag.CodeGeneration/ClientGeneratorBase.cs +++ b/src/NSwag.CodeGeneration/ClientGeneratorBase.cs @@ -174,7 +174,12 @@ private List GetOperations(OpenApiDocument document) foreach (var p in pair.Value.ActualPathItem) { var operation = p.Value; - + + if (this.BaseSettings.ExcludeDeprecated && operation.IsDeprecated && !operationsToInclude.Contains(operation.OperationId)) + { + continue; + } + if ((operationsToInclude.Count is not 0 && !operationsToInclude.Contains(operation.OperationId)) || (operationsToExclude.Count is not 0 && operationsToExclude.Contains(operation.OperationId)) diff --git a/src/NSwag.CodeGeneration/ClientGeneratorBaseSettings.cs b/src/NSwag.CodeGeneration/ClientGeneratorBaseSettings.cs index dbd4b6984..b4ec98eec 100644 --- a/src/NSwag.CodeGeneration/ClientGeneratorBaseSettings.cs +++ b/src/NSwag.CodeGeneration/ClientGeneratorBaseSettings.cs @@ -65,6 +65,9 @@ protected ClientGeneratorBaseSettings() /// Gets or sets the operations that should be excluded from the generated client. public string[] ExcludedOperationIds { get; set; } + /// Gets or sets the value indicating if deprecated endpoints shall be rendered + public bool ExcludeDeprecated { get; set; } + /// Gets or sets a value indicating whether to reorder parameters (required first, optional at the end) and generate optional parameters. public bool GenerateOptionalParameters { get; set; } diff --git a/src/NSwag.Commands/Commands/CodeGeneration/OpenApiToCSharpCommandBase.cs b/src/NSwag.Commands/Commands/CodeGeneration/OpenApiToCSharpCommandBase.cs index 5596d2e1d..0870802a4 100644 --- a/src/NSwag.Commands/Commands/CodeGeneration/OpenApiToCSharpCommandBase.cs +++ b/src/NSwag.Commands/Commands/CodeGeneration/OpenApiToCSharpCommandBase.cs @@ -50,6 +50,13 @@ public string[] ExcludedOperationIds set => Settings.ExcludedOperationIds = value; } + [Argument(Name = "ExcludeDeprecated", IsRequired = false, Description = "Specifies if deprecated endpoints should be generated")] + public bool ExcludeDeprecated + { + get => Settings.ExcludeDeprecated; + set => Settings.ExcludeDeprecated = value; + } + [Argument(Name = "AdditionalNamespaceUsages", IsRequired = false, Description = "The additional namespace usages.")] public string[] AdditionalNamespaceUsages { diff --git a/src/NSwag.Commands/Commands/CodeGeneration/OpenApiToTypeScriptClientCommand.cs b/src/NSwag.Commands/Commands/CodeGeneration/OpenApiToTypeScriptClientCommand.cs index d8842d81e..90d2851a4 100644 --- a/src/NSwag.Commands/Commands/CodeGeneration/OpenApiToTypeScriptClientCommand.cs +++ b/src/NSwag.Commands/Commands/CodeGeneration/OpenApiToTypeScriptClientCommand.cs @@ -248,6 +248,13 @@ public string[] ExcludedOperationIds set => Settings.ExcludedOperationIds = value; } + [Argument(Name = "ExcludeDeprecated", IsRequired = false, Description = "Specifies if deprecated endpoints should be generated")] + public bool ExcludeDeprecated + { + get => Settings.ExcludeDeprecated; + set => Settings.ExcludeDeprecated = value; + } + [Argument(Name = "MarkOptionalProperties", IsRequired = false, Description = "Specifies whether to mark optional properties with ? (default: false).")] public bool MarkOptionalProperties { diff --git a/src/NSwag.Sample.NET100/nswag.json b/src/NSwag.Sample.NET100/nswag.json index e497178c7..cdf8baf98 100644 --- a/src/NSwag.Sample.NET100/nswag.json +++ b/src/NSwag.Sample.NET100/nswag.json @@ -87,6 +87,7 @@ "operationGenerationMode": "MultipleClientsFromOperationId", "includedOperationIds": [], "excludedOperationIds": [], + "excludeDeprecated": false, "markOptionalProperties": true, "generateCloneMethod": false, "typeStyle": "Class", diff --git a/src/NSwag.Sample.NET100Minimal/nswag.json b/src/NSwag.Sample.NET100Minimal/nswag.json index cbc20922e..d9a129963 100644 --- a/src/NSwag.Sample.NET100Minimal/nswag.json +++ b/src/NSwag.Sample.NET100Minimal/nswag.json @@ -52,6 +52,7 @@ "operationGenerationMode": "MultipleClientsFromOperationId", "includedOperationIds": [], "excludedOperationIds": [], + "excludeDeprecated": false, "markOptionalProperties": true, "generateCloneMethod": false, "typeStyle": "Class", diff --git a/src/NSwag.Sample.NET80/nswag.json b/src/NSwag.Sample.NET80/nswag.json index 0891487ac..b2215b63a 100644 --- a/src/NSwag.Sample.NET80/nswag.json +++ b/src/NSwag.Sample.NET80/nswag.json @@ -87,6 +87,7 @@ "operationGenerationMode": "MultipleClientsFromOperationId", "includedOperationIds": [], "excludedOperationIds": [], + "excludeDeprecated": false, "markOptionalProperties": true, "generateCloneMethod": false, "typeStyle": "Class", diff --git a/src/NSwag.Sample.NET80Minimal/nswag.json b/src/NSwag.Sample.NET80Minimal/nswag.json index c5a6c1927..d21e72aae 100644 --- a/src/NSwag.Sample.NET80Minimal/nswag.json +++ b/src/NSwag.Sample.NET80Minimal/nswag.json @@ -52,6 +52,7 @@ "operationGenerationMode": "MultipleClientsFromOperationId", "includedOperationIds": [], "excludedOperationIds": [], + "excludeDeprecated": false, "markOptionalProperties": true, "generateCloneMethod": false, "typeStyle": "Class", diff --git a/src/NSwag.Sample.NET90/nswag.json b/src/NSwag.Sample.NET90/nswag.json index 004c6595b..e32013f73 100644 --- a/src/NSwag.Sample.NET90/nswag.json +++ b/src/NSwag.Sample.NET90/nswag.json @@ -87,6 +87,7 @@ "operationGenerationMode": "MultipleClientsFromOperationId", "includedOperationIds": [], "excludedOperationIds": [], + "excludeDeprecated": false, "markOptionalProperties": true, "generateCloneMethod": false, "typeStyle": "Class", diff --git a/src/NSwag.Sample.NET90Minimal/nswag.json b/src/NSwag.Sample.NET90Minimal/nswag.json index 95e31fb8c..2c0447bdd 100644 --- a/src/NSwag.Sample.NET90Minimal/nswag.json +++ b/src/NSwag.Sample.NET90Minimal/nswag.json @@ -52,6 +52,7 @@ "operationGenerationMode": "MultipleClientsFromOperationId", "includedOperationIds": [], "excludedOperationIds": [], + "excludeDeprecated": false, "markOptionalProperties": true, "generateCloneMethod": false, "typeStyle": "Class", diff --git a/src/NSwagStudio/Views/CodeGenerators/SwaggerToCSharpClientGeneratorView.xaml b/src/NSwagStudio/Views/CodeGenerators/SwaggerToCSharpClientGeneratorView.xaml index 369ca1717..63b0e4920 100644 --- a/src/NSwagStudio/Views/CodeGenerators/SwaggerToCSharpClientGeneratorView.xaml +++ b/src/NSwagStudio/Views/CodeGenerators/SwaggerToCSharpClientGeneratorView.xaml @@ -114,6 +114,11 @@ Text="{Binding Command.ExcludedOperationIds, Mode=TwoWay, Converter={StaticResource StringArrayConverter}, ConverterParameter=','}" Margin="0,0,0,12" /> + + diff --git a/src/NSwagStudio/Views/CodeGenerators/SwaggerToCSharpControllerGeneratorView.xaml b/src/NSwagStudio/Views/CodeGenerators/SwaggerToCSharpControllerGeneratorView.xaml index e461db676..d4e1e6db2 100644 --- a/src/NSwagStudio/Views/CodeGenerators/SwaggerToCSharpControllerGeneratorView.xaml +++ b/src/NSwagStudio/Views/CodeGenerators/SwaggerToCSharpControllerGeneratorView.xaml @@ -123,6 +123,12 @@ + + + diff --git a/src/NSwagStudio/Views/CodeGenerators/SwaggerToTypeScriptClientGeneratorView.xaml b/src/NSwagStudio/Views/CodeGenerators/SwaggerToTypeScriptClientGeneratorView.xaml index 269730571..e84d17285 100644 --- a/src/NSwagStudio/Views/CodeGenerators/SwaggerToTypeScriptClientGeneratorView.xaml +++ b/src/NSwagStudio/Views/CodeGenerators/SwaggerToTypeScriptClientGeneratorView.xaml @@ -134,6 +134,7 @@ The operation name detection and replacement strategy of the {controller} placeholder in the Class Name setting: + @@ -148,6 +149,11 @@ Text="{Binding Command.ExcludedOperationIds, Mode=TwoWay, Converter={StaticResource StringArrayConverter}, ConverterParameter=','}" Margin="0,0,0,12" /> + +