From c6e0d26ccc94127c36414a0ae5511822f8d52f68 Mon Sep 17 00:00:00 2001 From: Paulo Morgado <470455+paulomorgado@users.noreply.github.com> Date: Mon, 20 Oct 2025 14:04:59 +0100 Subject: [PATCH] Refactor code generation templates and enhance test coverage. - Added `CSharpCompiler.AssertCompile` assertions across multiple test files to ensure generated code compiles successfully. - Introduced new test cases for nullable path parameters, query string handling (arrays, dictionaries, deep objects), and OpenAPI specifications. - Refactored path and query parameter handling in Liquid templates for improved readability and correctness. - Generated auto-verified test outputs for new test cases. - Improved handling of constructor parameters in generated clients. --- .../AllowNullableBodyParametersTests.cs | 31 +- .../ArrayParameterTests.cs | 54 +- .../CSharpClientSettingsTests.cs | 45 ++ .../CSharpCompiler.TypeStubs.cs | 47 ++ .../CSharpCompiler.cs | 15 + .../ClientGenerationTests.cs | 6 +- .../CodeGenerationTests.cs | 40 ++ .../ControllerGenerationFormatTests.cs | 10 + .../IssueTests.cs | 532 ++++++++++++++++ .../RequiredParameterTests.cs | 13 +- ...GuardForOptionalBodyParameter.verified.txt | 2 +- ...thAllowNullableBodyParameters.verified.txt | 4 +- ...utAllowNullableBodyParameters.verified.txt | 4 +- ...at_is_csv_then_do_not_explode.verified.txt | 16 +- ...nFormat_is_multi_then_explode.verified.txt | 7 +- ...lode_explode=-explode-- true,.verified.txt | 7 +- ...le-- -form-, -explode-- true,.verified.txt | 7 +- ...lode_explode=-style-- -form-,.verified.txt | 7 +- ...ly_true_then_explode_explode=.verified.txt | 7 +- ...ode_explode=-explode-- false,.verified.txt | 16 +- ...e-- -form-, -explode-- false,.verified.txt | 16 +- ..._array_then_CSharp_is_correct.verified.txt | 16 +- ...be_added_in_foreach_in_csharp.verified.txt | 2 +- ...hen_correct_ctor_is_generated.verified.txt | 2 +- ...teRequestMessage_is_generated.verified.txt | 2 +- ...llow_nullable_path_parameters.verified.txt | 378 +++++++++++ ...error_when_character_is_quote.verified.txt | 287 +++++++++ ...query_string_array_parameters.verified.txt | 536 ++++++++++++++++ ...string_deep_object_parameters.verified.txt | 599 ++++++++++++++++++ ..._string_dictionary_parameters.verified.txt | 297 +++++++++ .../Snapshots/JIRA_OpenAPI.verified.txt | 485 +++++++++++--- ...roperties_are_correctly_named.verified.txt | 5 +- ...ay_and_should_not_be_exploded.verified.txt | 14 +- ...e_kind_then_they_are_included.verified.txt | 14 +- ...bject_parameters_are_expanded.verified.txt | 5 +- ...bject_parameters_are_expanded.verified.txt | 5 +- ...bject_parameters_are_expanded.verified.txt | 5 +- ...bject_parameters_are_expanded.verified.txt | 5 +- .../Snapshots/ShipBob_OpenAPI.verified.txt | 5 +- ...enerate_with_required_keyword.verified.txt | 310 +++++++++ ...enerate_with_required_keyword.verified.txt | 310 +++++++++ .../WrapResponsesTests.cs | 18 + .../Client.Class.PathParameter.liquid | 32 +- .../Client.Class.QueryParameter.liquid | 49 +- .../Templates/Client.Class.liquid | 21 +- .../VerifyHelper.cs | 17 + 46 files changed, 4053 insertions(+), 252 deletions(-) create mode 100644 src/NSwag.CodeGeneration.CSharp.Tests/CSharpCompiler.TypeStubs.cs create mode 100644 src/NSwag.CodeGeneration.CSharp.Tests/IssueTests.cs create mode 100644 src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/IssueTests.Issue4587_allow_nullable_path_parameters.verified.txt create mode 100644 src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/IssueTests.Issue5209_Single_character_path_without_parameter_causes_compilation_error_when_character_is_quote.verified.txt create mode 100644 src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/IssueTests.Issue5260_compilation_error_in_query_string_array_parameters.verified.txt create mode 100644 src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/IssueTests.Issue5260_compilation_error_in_query_string_deep_object_parameters.verified.txt create mode 100644 src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/IssueTests.Issue5260_compilation_error_in_query_string_dictionary_parameters.verified.txt create mode 100644 src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/UseRequiredKeywordNewtonsoftJsonSchemaGeneratorTests.When_setting_is_enabled_properties_with_required_keyword_should_generate_with_required_keyword.verified.txt create mode 100644 src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/UseRequiredKeywordSystemTextJsonSchemaGeneratorSettingsTests.When_setting_is_enabled_properties_with_required_keyword_should_generate_with_required_keyword.verified.txt diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/AllowNullableBodyParametersTests.cs b/src/NSwag.CodeGeneration.CSharp.Tests/AllowNullableBodyParametersTests.cs index ae34b0c38..bfe7133ed 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/AllowNullableBodyParametersTests.cs +++ b/src/NSwag.CodeGeneration.CSharp.Tests/AllowNullableBodyParametersTests.cs @@ -1,9 +1,10 @@ using Microsoft.AspNetCore.Mvc; using NJsonSchema.NewtonsoftJson.Generation; using NSwag.CodeGeneration.OperationNameGenerators; +using NSwag.CodeGeneration.Tests; using NSwag.Generation.WebApi; using System.ComponentModel.DataAnnotations; -using NSwag.CodeGeneration.Tests; +using System.Reflection; namespace NSwag.CodeGeneration.CSharp.Tests { @@ -46,7 +47,11 @@ public async Task TestNoGuardForOptionalBodyParameter() { UseBaseUrl = false, GenerateClientInterfaces = true, - OperationNameGenerator = new SingleClientFromOperationIdOperationNameGenerator() + OperationNameGenerator = new SingleClientFromOperationIdOperationNameGenerator(), + CSharpGeneratorSettings = + { + Namespace = VerifyHelper.GetNameSpace(), + }, }); var code = codeGen.GenerateFile(); @@ -61,12 +66,23 @@ public async Task TestNullableBodyWithAllowNullableBodyParameters() { // Arrange var generator = await GenerateCode(true); + generator.Settings.CSharpGeneratorSettings.Namespace = VerifyHelper.GetNameSpace(); // Act var code = generator.GenerateFile(); // Assert await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code + @" +namespace AllowNullableBodyParametersTests.TestNullableBodyWithAllowNullableBodyParameters +{ + public class MyBaseClass + { + public MyBaseClass(MyConfig configuration) {} + } + public class MyConfig {} +} +"); } [Fact] @@ -74,12 +90,23 @@ public async Task TestNullableBodyWithoutAllowNullableBodyParameters() { // Arrange var generator = await GenerateCode(false); + generator.Settings.CSharpGeneratorSettings.Namespace = VerifyHelper.GetNameSpace(); // Act var code = generator.GenerateFile(); // Assert await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code + @" +namespace AllowNullableBodyParametersTests.TestNullableBodyWithoutAllowNullableBodyParameters +{ + public class MyBaseClass + { + public MyBaseClass(MyConfig configuration) {} + } + public class MyConfig {} +} +"); } private static async Task GenerateCode(bool allowNullableBodyParameters) diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/ArrayParameterTests.cs b/src/NSwag.CodeGeneration.CSharp.Tests/ArrayParameterTests.cs index 4c6027f2d..2176364c5 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/ArrayParameterTests.cs +++ b/src/NSwag.CodeGeneration.CSharp.Tests/ArrayParameterTests.cs @@ -60,7 +60,14 @@ public async Task When_parameter_is_array_then_CSharp_is_correct() var document = await OpenApiDocument.FromJsonAsync(swagger); // Act - var settings = new CSharpClientGeneratorSettings { ClassName = "MyClass" }; + var settings = new CSharpClientGeneratorSettings + { + ClassName = "MyClass", + CSharpGeneratorSettings = + { + Namespace = VerifyHelper.GetNameSpace(), + }, + }; var generator = new CSharpClientGenerator(document, settings); var code = generator.GenerateFile(); @@ -136,7 +143,14 @@ public async Task When_explode_is_false_then_do_not_explode(string explode) var document = await OpenApiDocument.FromJsonAsync(json); // Act - var settings = new CSharpClientGeneratorSettings { ClassName = "MyClass" }; + var settings = new CSharpClientGeneratorSettings + { + ClassName = "MyClass", + CSharpGeneratorSettings = + { + Namespace = VerifyHelper.GetNameSpace(), + }, + }; var generator = new CSharpClientGenerator(document, settings); var code = generator.GenerateFile(); @@ -214,7 +228,14 @@ public async Task When_explode_is_explicitly_or_implicitly_true_then_explode(str var document = await OpenApiDocument.FromJsonAsync(json); // Act - var settings = new CSharpClientGeneratorSettings { ClassName = "MyClass" }; + var settings = new CSharpClientGeneratorSettings + { + ClassName = "MyClass", + CSharpGeneratorSettings = + { + Namespace = VerifyHelper.GetNameSpace(), + }, + }; var generator = new CSharpClientGenerator(document, settings); var code = generator.GenerateFile(); @@ -280,7 +301,14 @@ public async Task When_CollectionFormat_is_csv_then_do_not_explode() var document = await OpenApiDocument.FromJsonAsync(swagger); // Act - var settings = new CSharpClientGeneratorSettings { ClassName = "MyClass" }; + var settings = new CSharpClientGeneratorSettings + { + ClassName = "MyClass", + CSharpGeneratorSettings = + { + Namespace = VerifyHelper.GetNameSpace(), + }, + }; var generator = new CSharpClientGenerator(document, settings); var code = generator.GenerateFile(); @@ -346,7 +374,14 @@ public async Task When_CollectionFormat_is_multi_then_explode() var document = await OpenApiDocument.FromJsonAsync(swagger); // Act - var settings = new CSharpClientGeneratorSettings { ClassName = "MyClass" }; + var settings = new CSharpClientGeneratorSettings + { + ClassName = "MyClass", + CSharpGeneratorSettings = + { + Namespace = VerifyHelper.GetNameSpace(), + }, + }; var generator = new CSharpClientGenerator(document, settings); var code = generator.GenerateFile(); @@ -421,7 +456,14 @@ public async Task when_content_is_formdata_with_property_array_then_content_shou var document = await OpenApiDocument.FromJsonAsync(json); // Act - var settings = new CSharpClientGeneratorSettings { ClassName = "MyClass" }; + var settings = new CSharpClientGeneratorSettings + { + ClassName = "MyClass", + CSharpGeneratorSettings = + { + Namespace = VerifyHelper.GetNameSpace(), + }, + }; var generator = new CSharpClientGenerator(document, settings); var code = generator.GenerateFile(); diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/CSharpClientSettingsTests.cs b/src/NSwag.CodeGeneration.CSharp.Tests/CSharpClientSettingsTests.cs index 0fa6f3675..6c2d8eb28 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/CSharpClientSettingsTests.cs +++ b/src/NSwag.CodeGeneration.CSharp.Tests/CSharpClientSettingsTests.cs @@ -48,6 +48,16 @@ public async Task When_ConfigurationClass_is_set_then_correct_ctor_is_generated( // Assert await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code + @" +namespace MyNamespace +{ + public class MyBaseClass + { + public MyBaseClass(MyConfig configuration) {} + } + public class MyConfig {} +} +"); } [Fact] @@ -72,6 +82,17 @@ public async Task When_UseHttpRequestMessageCreationMethod_is_set_then_CreateReq // Assert await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code + @" +namespace MyNamespace +{ + public class MyBaseClass + { + public MyBaseClass(MyConfig configuration) {} + protected global::System.Threading.Tasks.Task CreateHttpRequestMessageAsync(global::System.Threading.CancellationToken ct) { return default; } + } + public class MyConfig {} +} +"); } [Fact] @@ -162,6 +183,12 @@ public async Task When_custom_http_client_type_is_specified_then_an_instance_of_ // Assert await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code + @" +namespace CustomNamespace +{ + public class CustomHttpClient : global::System.Net.Http.HttpClient { } +} +"); } [Fact] @@ -232,6 +259,12 @@ public async Task When_client_base_interface_is_specified_then_client_interface_ // Assert await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code + @" +namespace MyNamespace +{ + public interface IClientBase { } +} +"); } [Fact] @@ -256,6 +289,12 @@ public async Task When_client_base_interface_is_specified_with_access_modifier_t // Assert await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code + @" +namespace MyNamespace +{ + public interface IClientBase { } +} +"); } [Fact] @@ -307,6 +346,12 @@ public async Task When_client_interface_generation_is_enabled_and_suppressed_the // Assert await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code + @" +namespace MyNamespace +{ + public interface IFooClient { } +} +"); } public class OperationSelectionTestData : IEnumerable diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/CSharpCompiler.TypeStubs.cs b/src/NSwag.CodeGeneration.CSharp.Tests/CSharpCompiler.TypeStubs.cs new file mode 100644 index 000000000..d9e7e713c --- /dev/null +++ b/src/NSwag.CodeGeneration.CSharp.Tests/CSharpCompiler.TypeStubs.cs @@ -0,0 +1,47 @@ +namespace System.Web.Http +{ + public class ApiController { } + public abstract class ParameterBindingAttribute : global::System.Attribute + { + public abstract System.Web.Http.Controllers.HttpParameterBinding GetBinding(global::System.Web.Http.Controllers.HttpParameterDescriptor parameter); + } + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)] + public class HttpGetAttribute : global::System.Attribute { } + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)] + public class HttpPostAttribute : global::System.Attribute { } + [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property, AllowMultiple = false, Inherited = true)] + public class FromUriAttribute : global::System.Attribute { } + [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property, AllowMultiple = false, Inherited = true)] + public class FromBodyAttribute : global::System.Attribute { } + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = false)] + public class RouteAttribute : global::System.Attribute + { + public RouteAttribute(string template) { } + } +} + +namespace System.Web.Http.Controllers +{ + public abstract class HttpParameterBinding + { + protected HttpParameterBinding(global::System.Web.Http.Controllers.HttpParameterDescriptor parameter) { } + public dynamic ActionArguments { get; } + public dynamic Descriptor { get; } + public abstract System.Threading.Tasks.Task ExecuteBindingAsync(global::System.Web.Http.Metadata.ModelMetadataProvider metadataProvider, global::System.Web.Http.Controllers.HttpActionContext actionContext, global::System.Threading.CancellationToken cancellationToken); + } + public abstract class HttpParameterDescriptor + { + public string ParameterName { get; } + public dynamic ActionArguments { get; } + } + public abstract class HttpActionContext + { + public dynamic ActionArguments { get; } + public dynamic Request { get; } + } +} + +namespace System.Web.Http.Metadata +{ + public abstract class ModelMetadataProvider { } +} diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/CSharpCompiler.cs b/src/NSwag.CodeGeneration.CSharp.Tests/CSharpCompiler.cs index 8773a571d..75a956e16 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/CSharpCompiler.cs +++ b/src/NSwag.CodeGeneration.CSharp.Tests/CSharpCompiler.cs @@ -15,12 +15,27 @@ static CSharpCompiler() .Append(MetadataReference.CreateFromFile(typeof(HttpClient).Assembly.Location)) .Append(MetadataReference.CreateFromFile(typeof(Microsoft.AspNetCore.Mvc.FileResult).Assembly.Location)) .Append(MetadataReference.CreateFromFile(typeof(Microsoft.AspNetCore.Http.IFormFile).Assembly.Location)) + .Append(MetadataReference.CreateFromFile(typeof(Microsoft.AspNetCore.Http.HttpRequest).Assembly.Location)) + .Append(MetadataReference.CreateFromFile(typeof(Microsoft.Extensions.Primitives.StringValues).Assembly.Location)) + .Append(MetadataReference.CreateFromFile(typeof(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo).Assembly.Location)) .Append(MetadataReference.CreateFromFile(typeof(Newtonsoft.Json.JsonSerializer).Assembly.Location)) .Append(MetadataReference.CreateFromFile(typeof(System.Net.HttpStatusCode).Assembly.Location)) .Append(MetadataReference.CreateFromFile(typeof(System.ComponentModel.DataAnnotations.RangeAttribute).Assembly.Location)) .Append(MetadataReference.CreateFromFile(typeof(System.Collections.ObjectModel.ObservableCollection<>).Assembly.Location)) .Append(MetadataReference.CreateFromFile(typeof(System.Runtime.Serialization.EnumMemberAttribute).Assembly.Location)) .Append(MetadataReference.CreateFromFile(typeof(System.Text.Json.Serialization.JsonConverter).Assembly.Location)) + // stubs + .Append(MetadataReference.CreateFromFile(typeof(System.Web.Http.ApiController).Assembly.Location)) + .Append(MetadataReference.CreateFromFile(typeof(System.Web.Http.FromBodyAttribute).Assembly.Location)) + .Append(MetadataReference.CreateFromFile(typeof(System.Web.Http.FromUriAttribute).Assembly.Location)) + .Append(MetadataReference.CreateFromFile(typeof(System.Web.Http.HttpGetAttribute).Assembly.Location)) + .Append(MetadataReference.CreateFromFile(typeof(System.Web.Http.HttpPostAttribute).Assembly.Location)) + .Append(MetadataReference.CreateFromFile(typeof(System.Web.Http.ParameterBindingAttribute).Assembly.Location)) + .Append(MetadataReference.CreateFromFile(typeof(System.Web.Http.RouteAttribute).Assembly.Location)) + .Append(MetadataReference.CreateFromFile(typeof(System.Web.Http.Controllers.HttpActionContext).Assembly.Location)) + .Append(MetadataReference.CreateFromFile(typeof(System.Web.Http.Controllers.HttpParameterBinding).Assembly.Location)) + .Append(MetadataReference.CreateFromFile(typeof(System.Web.Http.Controllers.HttpParameterDescriptor).Assembly.Location)) + .Append(MetadataReference.CreateFromFile(typeof(System.Web.Http.Metadata.ModelMetadataProvider).Assembly.Location)) .ToList(); } diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/ClientGenerationTests.cs b/src/NSwag.CodeGeneration.CSharp.Tests/ClientGenerationTests.cs index d309bdb3c..083fe917a 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/ClientGenerationTests.cs +++ b/src/NSwag.CodeGeneration.CSharp.Tests/ClientGenerationTests.cs @@ -8,19 +8,21 @@ public class ClientGenerationTests [Fact] public async Task CanGenerateFromJiraOpenApiSpecification() { + // Jira's OpenAPI spec generates code like this: + //// public bool ShowDaysInColumn { get; set; } = MyNamespace.bool.False; await VerifyOutput("JIRA_OpenAPI", "jira-open-api.json", compile: false); } [Fact] public async Task CanGenerateFromShipBobOpenApiSpecification() { - await VerifyOutput("ShipBob_OpenAPI", "shipbob-2025-07.json"); + await VerifyOutput("ShipBob_OpenAPI", "shipbob-2025-07.json", compile: true); } [Fact] public async Task CanGenerateFromNhsSpineServicesOpenApiSpecification() { - await VerifyOutput("NHS_SpineServices_OpenAPI", "nhs-spineservices.json"); + await VerifyOutput("NHS_SpineServices_OpenAPI", "nhs-spineservices.json", compile: true); } private static async Task VerifyOutput(string name, string fileName, bool compile = true) diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/CodeGenerationTests.cs b/src/NSwag.CodeGeneration.CSharp.Tests/CodeGenerationTests.cs index 57f1c24cf..4b4362db5 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/CodeGenerationTests.cs +++ b/src/NSwag.CodeGeneration.CSharp.Tests/CodeGenerationTests.cs @@ -60,6 +60,15 @@ public async Task When_generating_CSharp_code_with_SystemTextJson_and_JsonSerial // Assert await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code + @" +namespace MyNamespace +{ + partial class Client + { + static global::System.Text.Json.JsonSerializerOptions TestJsonSerializerSettingsTransformationMethod(global::System.Text.Json.JsonSerializerOptions settings) { return settings; } + } +} +"); } [Fact] @@ -78,6 +87,15 @@ public async Task When_generating_CSharp_code_with_NewtonsoftJson_and_JsonSerial // Assert await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code + @" +namespace MyNamespace +{ + partial class Client + { + static global::Newtonsoft.Json.JsonSerializerSettings TestJsonSerializerSettingsTransformationMethod(global::Newtonsoft.Json.JsonSerializerSettings settings) { return settings; } + } +} +"); } [Fact] @@ -96,6 +114,17 @@ public async Task When_generating_CSharp_code_with_SystemTextJson_and_JsonConver // Assert await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code + @" +#nullable disable +namespace MyNamespace { + class CustomConverter1 : global::System.Text.Json.Serialization.JsonConverter + { + public override Client Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) { return default(Client); } + public override void Write(global::System.Text.Json.Utf8JsonWriter writer, Client value, global::System.Text.Json.JsonSerializerOptions options) { } + } + class CustomConverter2 : CustomConverter1 { } +} +"); } [Fact] @@ -115,6 +144,17 @@ public async Task When_generating_CSharp_code_with_SystemTextJson_and_GenerateJs // Assert await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code + @" +#nullable disable +namespace MyNamespace { + class CustomConverter1 : global::System.Text.Json.Serialization.JsonConverter + { + public override Client Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) { return default(Client); } + public override void Write(global::System.Text.Json.Utf8JsonWriter writer, Client value, global::System.Text.Json.JsonSerializerOptions options) { } + } + class CustomConverter2 : CustomConverter1 { } +} +"); } [Fact] diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/ControllerGenerationFormatTests.cs b/src/NSwag.CodeGeneration.CSharp.Tests/ControllerGenerationFormatTests.cs index c77202228..3b9cf11b0 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/ControllerGenerationFormatTests.cs +++ b/src/NSwag.CodeGeneration.CSharp.Tests/ControllerGenerationFormatTests.cs @@ -226,6 +226,13 @@ public async Task When_the_generation_of_dto_classes_are_disabled_then_file_is_g // Assert await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code + @" +namespace MyNamespace +{ + public class ComplexType {} + public class ComplexTypeResponse {} +} +"); } private static OpenApiDocument GetOpenApiDocument() @@ -434,6 +441,7 @@ public async Task When_controllertarget_aspnet_and_multiple_controllers_then_onl Assert.Equal(1, fromHeaderCustomBindingCount); await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code); } [Fact] @@ -471,6 +479,8 @@ public async Task When_controller_has_operation_with_header_parameter_then_parti // Assert await VerifyHelper.Verify(code); + + CSharpCompiler.AssertCompile(code); } } } diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/IssueTests.cs b/src/NSwag.CodeGeneration.CSharp.Tests/IssueTests.cs new file mode 100644 index 000000000..c45b751dc --- /dev/null +++ b/src/NSwag.CodeGeneration.CSharp.Tests/IssueTests.cs @@ -0,0 +1,532 @@ +using NSwag.CodeGeneration.OperationNameGenerators; +using NSwag.CodeGeneration.Tests; +using Parlot; + +namespace NSwag.CodeGeneration.CSharp.Tests +{ + public class IssueTests + { + [Fact] + public async Task Issue4587_allow_nullable_path_parameters() + { + // Arrange + var swagger = +@"{ + ""openapi"": ""3.0.1"", + ""paths"": { + ""/api/1/{param}"": { + ""get"": { + ""parameters"": [ + { + ""name"": ""param"", + ""in"": ""path"", + ""required"": false, + ""schema"": { + ""type"": ""string"", + } + } + ], + ""responses"": { + ""200"": { + ""content"": { + ""application/json"": { + ""schema"": { + ""type"": ""string"" + } + } + } + } + } + } + }, + ""/api/2/{param}/info"": { + ""get"": { + ""parameters"": [ + { + ""name"": ""param"", + ""in"": ""path"", + ""required"": false, + ""schema"": { + ""type"": ""string"", + } + } + ], + ""responses"": { + ""200"": { + ""content"": { + ""application/json"": { + ""schema"": { + ""type"": ""string"" + } + } + } + } + } + } + } + } +}"; + var document = await OpenApiDocument.FromJsonAsync(swagger); + + // Act + var codeGen = new CSharpClientGenerator(document, new CSharpClientGeneratorSettings() + { + UseBaseUrl = false, + GenerateClientInterfaces = true, + OperationNameGenerator = new SingleClientFromOperationIdOperationNameGenerator() + }); + + var code = codeGen.GenerateFile(); + + // Assert + await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code); + } + + [Fact] + public async Task Issue5209_Single_character_path_without_parameter_causes_compilation_error_when_character_is_quote() + { + // Arrange + var swagger = +@"{ + ""openapi"": ""3.0.3"", + ""info"": { + ""title"": ""Reproduce CSharp codegen edge case bug"", + ""version"": ""1.0"" + }, + ""paths"": { + ""/v1/this/is/a/test/path/?q='{param1}'"": { + ""get"": { + ""summary"": ""Query a thing"", + ""operationId"": ""GetThing"", + ""parameters"": [ + { + ""$ref"": ""#/components/parameters/param1Param"" + } + ], + ""responses"": { + ""200"": { + ""description"": ""OK"" + } + } + } + } + }, + ""components"": { + ""parameters"": { + ""param1Param"": { + ""in"": ""path"", + ""name"": ""param1"", + ""required"": true, + ""schema"": { + ""type"": ""string"" + } + } + } + } +}"; + var document = await OpenApiDocument.FromJsonAsync(swagger); + + // Act + var codeGen = new CSharpClientGenerator(document, new CSharpClientGeneratorSettings() + { + UseBaseUrl = false, + GenerateClientInterfaces = true, + OperationNameGenerator = new SingleClientFromOperationIdOperationNameGenerator() + }); + + var code = codeGen.GenerateFile(); + + // Assert + await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code); + } + + [Fact] + public async Task Issue5260_compilation_error_in_query_string_array_parameters() + { + // Arrange + var swagger = +@"{ + ""openapi"": ""3.0.1"", + ""paths"": { + ""/queryProductOrder1"": { + ""get"": { + ""tags"": [ + ""Order"" + ], + ""operationId"": ""getOrder1"", + ""parameters"": [ + { + ""name"": ""destinationFolderId"", + ""in"": ""query"", + ""required"": true, + ""style"": ""form"", + ""explode"": false, + ""schema"": { + ""type"": ""array"", + ""items"": { + ""type"": ""string"" + } + } + } + ], + ""responses"": { + ""200"": { + ""content"": { + ""application/json"": { + ""schema"": { + ""type"": ""string"" + } + } + } + } + } + } + }, + ""/queryProductOrder2"": { + ""get"": { + ""tags"": [ + ""Order"" + ], + ""operationId"": ""getOrder2"", + ""parameters"": [ + { + ""name"": ""orderStatus"", + ""in"": ""query"", + ""style"": ""form"", + ""explode"": false, + ""schema"": { + ""type"": ""array"", + ""items"": { + ""type"": ""string"", + ""enum"": [ + ""Draft"", + ""Submitted"", + ""Running"", + ""Completed"", + ""Cancelled"", + ""In Error"", + ""Suspended"", + ""Order Configuration Queued"" + ] + } + } + } + ], + ""responses"": { + ""200"": { + ""content"": { + ""application/json"": { + ""schema"": { + ""type"": ""string"" + } + } + } + } + } + } + }, + ""/queryProductOrder3"": { + ""get"": { + ""tags"": [ + ""Order"" + ], + ""operationId"": ""getOrder3"", + ""parameters"": [ + { + ""name"": ""orderStatus"", + ""in"": ""query"", + ""style"": ""form"", + ""explode"": false, + ""schema"": { + ""type"": ""array"", + ""items"": { + ""type"": ""string"", + ""enum"": [ + ""Draft"", + ""Submitted"", + ""Running"", + ""Completed"", + ""Cancelled"", + ""In Error"", + ""Suspended"", + ""Order Configuration Queued"" + ] + } + } + }, + { + ""name"": ""destinationFolderId"", + ""in"": ""query"", + ""required"": true, + ""style"": ""form"", + ""explode"": false, + ""schema"": { + ""type"": ""array"", + ""items"": { + ""type"": ""string"" + } + } + } + ], + ""responses"": { + ""200"": { + ""content"": { + ""application/json"": { + ""schema"": { + ""type"": ""string"" + } + } + } + } + } + } + } + } +}"; + var document = await OpenApiDocument.FromJsonAsync(swagger); + + // Act + var codeGen = new CSharpClientGenerator(document, new CSharpClientGeneratorSettings() + { + UseBaseUrl = false, + GenerateClientInterfaces = true, + OperationNameGenerator = new SingleClientFromOperationIdOperationNameGenerator() + }); + + var code = codeGen.GenerateFile(); + + // Assert + await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code); + } + + [Fact] + public async Task Issue5260_compilation_error_in_query_string_dictionary_parameters() + { + // Arrange + var swagger = +@"{ + ""openapi"": ""3.0.1"", + ""info"": { + ""title"": ""Dynamic Dictionary Query API"", + ""version"": ""1.0.0"", + ""description"": ""An endpoint that accepts arbitrary key-value pairs in the query string"" + }, + ""paths"": { + ""/dynamicQuery"": { + ""get"": { + ""summary"": ""Accept arbitrary key-value pairs via query string"", + ""operationId"": ""getDynamicQuery"", + ""parameters"": [ + { + ""name"": ""params"", + ""in"": ""query"", + ""style"": ""deepObject"", + ""explode"": true, + ""schema"": { + ""type"": ""object"", + ""additionalProperties"": { + ""type"": ""string"" + } + }, + ""description"": ""Dictionary of arbitrary key-value pairs"" + } + ], + ""responses"": { + ""200"": { + ""description"": ""Success"", + ""content"": { + ""application/json"": { + ""schema"": { + ""type"": ""object"", + ""additionalProperties"": { + ""type"": ""string"" + } + } + } + } + } + } + } + } + } +}"; + var document = await OpenApiDocument.FromJsonAsync(swagger); + + // Act + var codeGen = new CSharpClientGenerator(document, new CSharpClientGeneratorSettings() + { + UseBaseUrl = false, + GenerateClientInterfaces = true, + OperationNameGenerator = new SingleClientFromOperationIdOperationNameGenerator() + }); + + var code = codeGen.GenerateFile(); + + // Assert + await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code); + } + + [Fact] + public async Task Issue5260_compilation_error_in_query_string_deep_object_parameters() + { + // Arrange + var swagger = +@"{ + ""openapi"": ""3.0.1"", + ""paths"": { + ""/queryProductOrder1"": { + ""get"": { + ""tags"": [ + ""Order"" + ], + ""operationId"": ""getOrder1"", + ""parameters"": [ + { + ""name"": ""params"", + ""in"": ""query"", + ""required"": true, + ""style"": ""deepObject"", + ""explode"": true, + ""schema"": { + ""type"": ""object"", + ""properties"": { + ""destinationFolderId"": { + ""type"": ""string"", + } + }, + ""required"": [""destinationFolderId""] + } + } + ], + ""responses"": { + ""200"": { + ""content"": { + ""application/json"": { + ""schema"": { + ""type"": ""string"" + } + } + } + } + } + } + }, + ""/queryProductOrder2"": { + ""get"": { + ""tags"": [ + ""Order"" + ], + ""operationId"": ""getOrder2"", + ""parameters"": [ + { + ""name"": ""params"", + ""in"": ""query"", + ""style"": ""deepObject"", + ""explode"": true, + ""schema"": { + ""type"": ""object"", + ""properties"": { + ""orderStatus"": { + ""type"": ""string"", + ""enum"": [ + ""Draft"", + ""Submitted"", + ""Running"", + ""Completed"", + ""Cancelled"", + ""In Error"", + ""Suspended"", + ""Order Configuration Queued"" + ] + } + } + } + } + ], + ""responses"": { + ""200"": { + ""content"": { + ""application/json"": { + ""schema"": { + ""type"": ""string"" + } + } + } + } + } + } + }, + ""/queryProductOrder3"": { + ""get"": { + ""tags"": [ + ""Order"" + ], + ""operationId"": ""getOrder3"", + ""parameters"": [ + { + ""name"": ""params"", + ""in"": ""query"", + ""required"": true, + ""style"": ""deepObject"", + ""explode"": true, + ""schema"": { + ""type"": ""object"", + ""properties"": { + ""orderStatus"": { + ""type"": ""string"", + ""enum"": [ + ""Draft"", + ""Submitted"", + ""Running"", + ""Completed"", + ""Cancelled"", + ""In Error"", + ""Suspended"", + ""Order Configuration Queued"" + ] + }, + ""destinationFolderId"": { + ""type"": ""string"", + } + }, + ""required"": [""destinationFolderId""] + } + } + ], + ""responses"": { + ""200"": { + ""content"": { + ""application/json"": { + ""schema"": { + ""type"": ""string"" + } + } + } + } + } + } + } + } +}"; + var document = await OpenApiDocument.FromJsonAsync(swagger); + + // Act + var codeGen = new CSharpClientGenerator(document, new CSharpClientGeneratorSettings() + { + UseBaseUrl = false, + GenerateClientInterfaces = true, + OperationNameGenerator = new SingleClientFromOperationIdOperationNameGenerator() + }); + + var code = codeGen.GenerateFile(); + + // Assert + await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code); + } + } +} diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/RequiredParameterTests.cs b/src/NSwag.CodeGeneration.CSharp.Tests/RequiredParameterTests.cs index e87cdab8c..9a429f2a2 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/RequiredParameterTests.cs +++ b/src/NSwag.CodeGeneration.CSharp.Tests/RequiredParameterTests.cs @@ -59,7 +59,7 @@ public async Task When_setting_is_enabled_properties_with_required_attribute_sho CSharpCompiler.AssertCompile(code); } - [Fact(Skip = "The C#11 required keyword does not mark schema properties as required")] + [Fact(/*Skip = "The C#11 required keyword does not mark schema properties as required"*/)] public async Task When_setting_is_enabled_properties_with_required_keyword_should_generate_with_required_keyword() { // Act @@ -67,7 +67,16 @@ public async Task When_setting_is_enabled_properties_with_required_keyword_shoul // Assert await VerifyHelper.Verify(code); - CSharpCompiler.AssertCompile(code); + CSharpCompiler.AssertCompile(code + @" +namespace MyNamespace +{ + public class MyBaseClass + { + public MyBaseClass(MyConfig configuration) {} + } + public class MyConfig {} +} +"); } [Fact] diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/AllowNullableBodyParametersTests.TestNoGuardForOptionalBodyParameter.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/AllowNullableBodyParametersTests.TestNoGuardForOptionalBodyParameter.verified.txt index 14ac150ff..6e08b44fb 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/AllowNullableBodyParametersTests.TestNoGuardForOptionalBodyParameter.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/AllowNullableBodyParametersTests.TestNoGuardForOptionalBodyParameter.verified.txt @@ -1,6 +1,6 @@  -namespace MyNamespace +namespace AllowNullableBodyParametersTests.TestNoGuardForOptionalBodyParameter { using System = global::System; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/AllowNullableBodyParametersTests.TestNullableBodyWithAllowNullableBodyParameters.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/AllowNullableBodyParametersTests.TestNullableBodyWithAllowNullableBodyParameters.verified.txt index 5ffb14524..cd5f6f306 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/AllowNullableBodyParametersTests.TestNullableBodyWithAllowNullableBodyParameters.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/AllowNullableBodyParametersTests.TestNullableBodyWithAllowNullableBodyParameters.verified.txt @@ -1,6 +1,6 @@  -namespace MyNamespace +namespace AllowNullableBodyParametersTests.TestNullableBodyWithAllowNullableBodyParameters { using System = global::System; @@ -14,7 +14,7 @@ namespace MyNamespace 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 TestClient(MyConfig configuration) : base(configuration) + public TestClient(string baseUrl, MyConfig configuration) : base(configuration) #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. { BaseUrl = baseUrl; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/AllowNullableBodyParametersTests.TestNullableBodyWithoutAllowNullableBodyParameters.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/AllowNullableBodyParametersTests.TestNullableBodyWithoutAllowNullableBodyParameters.verified.txt index 9be274a46..e4b9db09b 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/AllowNullableBodyParametersTests.TestNullableBodyWithoutAllowNullableBodyParameters.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/AllowNullableBodyParametersTests.TestNullableBodyWithoutAllowNullableBodyParameters.verified.txt @@ -1,6 +1,6 @@  -namespace MyNamespace +namespace AllowNullableBodyParametersTests.TestNullableBodyWithoutAllowNullableBodyParameters { using System = global::System; @@ -14,7 +14,7 @@ namespace MyNamespace 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 TestClient(MyConfig configuration) : base(configuration) + public TestClient(string baseUrl, MyConfig configuration) : base(configuration) #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. { BaseUrl = baseUrl; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_CollectionFormat_is_csv_then_do_not_explode.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_CollectionFormat_is_csv_then_do_not_explode.verified.txt index 331a83508..437a70bb6 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_CollectionFormat_is_csv_then_do_not_explode.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_CollectionFormat_is_csv_then_do_not_explode.verified.txt @@ -1,6 +1,6 @@  -namespace MyNamespace +namespace ArrayParameterTests.When_CollectionFormat_is_csv_then_do_not_explode { using System = global::System; @@ -77,20 +77,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (elementId != null) { - bool isAfterFirst = false; foreach (var item_ in elementId) { - if (!isAfterFirst) - { - urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('='); - } - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append(','); - isAfterFirst = true; - } - if (isAfterFirst) - { - urlBuilder_.Length--; - urlBuilder_.Append('&'); + urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('='); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } } urlBuilder_.Length--; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_CollectionFormat_is_multi_then_explode.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_CollectionFormat_is_multi_then_explode.verified.txt index 5e685c6b9..e649c32bf 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_CollectionFormat_is_multi_then_explode.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_CollectionFormat_is_multi_then_explode.verified.txt @@ -1,6 +1,6 @@  -namespace MyNamespace +namespace ArrayParameterTests.When_CollectionFormat_is_multi_then_explode { using System = global::System; @@ -77,7 +77,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (elementId != null) { - foreach (var item_ in elementId) { urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in elementId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode_explode=-explode-- true,.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode_explode=-explode-- true,.verified.txt index 7ab869a9a..0bd3cf6d0 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode_explode=-explode-- true,.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode_explode=-explode-- true,.verified.txt @@ -1,6 +1,6 @@  -namespace MyNamespace +namespace ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode { using System = global::System; @@ -78,7 +78,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (elementId != null) { - foreach (var item_ in elementId) { urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in elementId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode_explode=-style-- -form-, -explode-- true,.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode_explode=-style-- -form-, -explode-- true,.verified.txt index 7ab869a9a..0bd3cf6d0 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode_explode=-style-- -form-, -explode-- true,.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode_explode=-style-- -form-, -explode-- true,.verified.txt @@ -1,6 +1,6 @@  -namespace MyNamespace +namespace ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode { using System = global::System; @@ -78,7 +78,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (elementId != null) { - foreach (var item_ in elementId) { urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in elementId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode_explode=-style-- -form-,.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode_explode=-style-- -form-,.verified.txt index 7ab869a9a..0bd3cf6d0 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode_explode=-style-- -form-,.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode_explode=-style-- -form-,.verified.txt @@ -1,6 +1,6 @@  -namespace MyNamespace +namespace ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode { using System = global::System; @@ -78,7 +78,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (elementId != null) { - foreach (var item_ in elementId) { urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in elementId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode_explode=.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode_explode=.verified.txt index 7ab869a9a..0bd3cf6d0 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode_explode=.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode_explode=.verified.txt @@ -1,6 +1,6 @@  -namespace MyNamespace +namespace ArrayParameterTests.When_explode_is_explicitly_or_implicitly_true_then_explode { using System = global::System; @@ -78,7 +78,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (elementId != null) { - foreach (var item_ in elementId) { urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in elementId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_false_then_do_not_explode_explode=-explode-- false,.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_false_then_do_not_explode_explode=-explode-- false,.verified.txt index 99a39df3e..e84ae289b 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_false_then_do_not_explode_explode=-explode-- false,.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_false_then_do_not_explode_explode=-explode-- false,.verified.txt @@ -1,6 +1,6 @@  -namespace MyNamespace +namespace ArrayParameterTests.When_explode_is_false_then_do_not_explode { using System = global::System; @@ -78,20 +78,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (elementId != null) { - bool isAfterFirst = false; foreach (var item_ in elementId) { - if (!isAfterFirst) - { - urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('='); - } - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append(','); - isAfterFirst = true; - } - if (isAfterFirst) - { - urlBuilder_.Length--; - urlBuilder_.Append('&'); + urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('='); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } } urlBuilder_.Length--; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_false_then_do_not_explode_explode=-style-- -form-, -explode-- false,.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_false_then_do_not_explode_explode=-style-- -form-, -explode-- false,.verified.txt index 99a39df3e..e84ae289b 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_false_then_do_not_explode_explode=-style-- -form-, -explode-- false,.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_explode_is_false_then_do_not_explode_explode=-style-- -form-, -explode-- false,.verified.txt @@ -1,6 +1,6 @@  -namespace MyNamespace +namespace ArrayParameterTests.When_explode_is_false_then_do_not_explode { using System = global::System; @@ -78,20 +78,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (elementId != null) { - bool isAfterFirst = false; foreach (var item_ in elementId) { - if (!isAfterFirst) - { - urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('='); - } - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append(','); - isAfterFirst = true; - } - if (isAfterFirst) - { - urlBuilder_.Length--; - urlBuilder_.Append('&'); + urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('='); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } } urlBuilder_.Length--; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_parameter_is_array_then_CSharp_is_correct.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_parameter_is_array_then_CSharp_is_correct.verified.txt index 331a83508..7c69f4bb5 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_parameter_is_array_then_CSharp_is_correct.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.When_parameter_is_array_then_CSharp_is_correct.verified.txt @@ -1,6 +1,6 @@  -namespace MyNamespace +namespace ArrayParameterTests.When_parameter_is_array_then_CSharp_is_correct { using System = global::System; @@ -77,20 +77,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (elementId != null) { - bool isAfterFirst = false; foreach (var item_ in elementId) { - if (!isAfterFirst) - { - urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('='); - } - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append(','); - isAfterFirst = true; - } - if (isAfterFirst) - { - urlBuilder_.Length--; - urlBuilder_.Append('&'); + urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('='); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } } urlBuilder_.Length--; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.when_content_is_formdata_with_property_array_then_content_should_be_added_in_foreach_in_csharp.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.when_content_is_formdata_with_property_array_then_content_should_be_added_in_foreach_in_csharp.verified.txt index 323897c6c..01ebfe99e 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.when_content_is_formdata_with_property_array_then_content_should_be_added_in_foreach_in_csharp.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ArrayParameterTests.when_content_is_formdata_with_property_array_then_content_should_be_added_in_foreach_in_csharp.verified.txt @@ -1,6 +1,6 @@  -namespace MyNamespace +namespace ArrayParameterTests.when_content_is_formdata_with_property_array_then_content_should_be_added_in_foreach_in_csharp { using System = global::System; 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..e179e5c1d 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 @@ -14,7 +14,7 @@ namespace MyNamespace 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(MyConfig configuration) : base(configuration) + public FooClient(string baseUrl, MyConfig configuration) : base(configuration) #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. { BaseUrl = baseUrl; 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..157012e71 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 @@ -15,7 +15,7 @@ namespace MyNamespace 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(MyConfig configuration, System.Net.Http.HttpClient httpClient) : base(configuration) + public FooClient(string baseUrl, MyConfig configuration, System.Net.Http.HttpClient httpClient) : base(configuration) #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. { BaseUrl = baseUrl; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/IssueTests.Issue4587_allow_nullable_path_parameters.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/IssueTests.Issue4587_allow_nullable_path_parameters.verified.txt new file mode 100644 index 000000000..0d4f64351 --- /dev/null +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/IssueTests.Issue4587_allow_nullable_path_parameters.verified.txt @@ -0,0 +1,378 @@ + + +namespace MyNamespace +{ + using System = global::System; + + public partial interface IClient + { + System.Threading.Tasks.Task _1Async(string param); + + System.Threading.Tasks.Task _1Async(string param, System.Threading.CancellationToken cancellationToken); + + System.Threading.Tasks.Task InfoAsync(string param); + + System.Threading.Tasks.Task InfoAsync(string param, System.Threading.CancellationToken cancellationToken); + + } + + public partial class Client : IClient + { + 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 Client(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. + { + _httpClient = httpClient; + Initialize(); + } + + private static Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings() + { + var settings = new Newtonsoft.Json.JsonSerializerSettings(); + UpdateJsonSerializerSettings(settings); + return settings; + } + + 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 _1Async(string param) + { + return _1Async(param, System.Threading.CancellationToken.None); + } + + public virtual async System.Threading.Tasks.Task _1Async(string param, 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(); + + // Operation Path: "api/1/{param}" + urlBuilder_.Append("api/1/"); + if (param != null) + { + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(param, System.Globalization.CultureInfo.InvariantCulture))); + } + else + if (urlBuilder_.Length > 0) 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); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + 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 InfoAsync(string param) + { + return InfoAsync(param, System.Threading.CancellationToken.None); + } + + public virtual async System.Threading.Tasks.Task InfoAsync(string param, 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(); + + // Operation Path: "api/2/{param}/info" + urlBuilder_.Append("api/2/"); + if (param != null) + { + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(param, System.Globalization.CultureInfo.InvariantCulture))); + } + else + if (urlBuilder_.Length > 0) urlBuilder_.Length--; + urlBuilder_.Append("/info"); + + 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); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + 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/IssueTests.Issue5209_Single_character_path_without_parameter_causes_compilation_error_when_character_is_quote.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/IssueTests.Issue5209_Single_character_path_without_parameter_causes_compilation_error_when_character_is_quote.verified.txt new file mode 100644 index 000000000..985413ece --- /dev/null +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/IssueTests.Issue5209_Single_character_path_without_parameter_causes_compilation_error_when_character_is_quote.verified.txt @@ -0,0 +1,287 @@ + + +namespace MyNamespace +{ + using System = global::System; + + public partial interface IClient + { + System.Threading.Tasks.Task GetThingAsync(string param1); + + System.Threading.Tasks.Task GetThingAsync(string param1, System.Threading.CancellationToken cancellationToken); + + } + + public partial class Client : IClient + { + 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 Client(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. + { + _httpClient = httpClient; + Initialize(); + } + + private static Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings() + { + var settings = new Newtonsoft.Json.JsonSerializerSettings(); + UpdateJsonSerializerSettings(settings); + return settings; + } + + 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 GetThingAsync(string param1) + { + return GetThingAsync(param1, System.Threading.CancellationToken.None); + } + + public virtual async System.Threading.Tasks.Task GetThingAsync(string param1, System.Threading.CancellationToken cancellationToken) + { + if (param1 == null) + throw new System.ArgumentNullException("param1"); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Method = new System.Net.Http.HttpMethod("GET"); + + var urlBuilder_ = new System.Text.StringBuilder(); + + // Operation Path: "v1/this/is/a/test/path/?q='{param1}'" + urlBuilder_.Append("v1/this/is/a/test/path/?q='"); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(param1, System.Globalization.CultureInfo.InvariantCulture))); + urlBuilder_.Append('\''); + + 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) + { + return; + } + 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/IssueTests.Issue5260_compilation_error_in_query_string_array_parameters.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/IssueTests.Issue5260_compilation_error_in_query_string_array_parameters.verified.txt new file mode 100644 index 000000000..31990d0a6 --- /dev/null +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/IssueTests.Issue5260_compilation_error_in_query_string_array_parameters.verified.txt @@ -0,0 +1,536 @@ + + +namespace MyNamespace +{ + using System = global::System; + + public partial interface IClient + { + System.Threading.Tasks.Task GetOrder1Async(System.Collections.Generic.IEnumerable destinationFolderId); + + System.Threading.Tasks.Task GetOrder1Async(System.Collections.Generic.IEnumerable destinationFolderId, System.Threading.CancellationToken cancellationToken); + + System.Threading.Tasks.Task GetOrder2Async(System.Collections.Generic.IEnumerable orderStatus); + + System.Threading.Tasks.Task GetOrder2Async(System.Collections.Generic.IEnumerable orderStatus, System.Threading.CancellationToken cancellationToken); + + System.Threading.Tasks.Task GetOrder3Async(System.Collections.Generic.IEnumerable orderStatus, System.Collections.Generic.IEnumerable destinationFolderId); + + System.Threading.Tasks.Task GetOrder3Async(System.Collections.Generic.IEnumerable orderStatus, System.Collections.Generic.IEnumerable destinationFolderId, System.Threading.CancellationToken cancellationToken); + + } + + public partial class Client : IClient + { + 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 Client(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. + { + _httpClient = httpClient; + Initialize(); + } + + private static Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings() + { + var settings = new Newtonsoft.Json.JsonSerializerSettings(); + UpdateJsonSerializerSettings(settings); + return settings; + } + + 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 GetOrder1Async(System.Collections.Generic.IEnumerable destinationFolderId) + { + return GetOrder1Async(destinationFolderId, System.Threading.CancellationToken.None); + } + + public virtual async System.Threading.Tasks.Task GetOrder1Async(System.Collections.Generic.IEnumerable destinationFolderId, System.Threading.CancellationToken cancellationToken) + { + if (destinationFolderId == null) + throw new System.ArgumentNullException("destinationFolderId"); + + 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(); + + // Operation Path: "queryProductOrder1" + urlBuilder_.Append("queryProductOrder1"); + urlBuilder_.Append('?'); + foreach (var item_ in destinationFolderId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("destinationFolderId")).Append('='); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(item_, 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); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + 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 GetOrder2Async(System.Collections.Generic.IEnumerable orderStatus) + { + return GetOrder2Async(orderStatus, System.Threading.CancellationToken.None); + } + + public virtual async System.Threading.Tasks.Task GetOrder2Async(System.Collections.Generic.IEnumerable orderStatus, 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(); + + // Operation Path: "queryProductOrder2" + urlBuilder_.Append("queryProductOrder2"); + urlBuilder_.Append('?'); + if (orderStatus != null) + { + foreach (var item_ in orderStatus) + { + urlBuilder_.Append(System.Uri.EscapeDataString("orderStatus")).Append('='); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(item_, 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); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + 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 GetOrder3Async(System.Collections.Generic.IEnumerable orderStatus, System.Collections.Generic.IEnumerable destinationFolderId) + { + return GetOrder3Async(orderStatus, destinationFolderId, System.Threading.CancellationToken.None); + } + + public virtual async System.Threading.Tasks.Task GetOrder3Async(System.Collections.Generic.IEnumerable orderStatus, System.Collections.Generic.IEnumerable destinationFolderId, System.Threading.CancellationToken cancellationToken) + { + if (destinationFolderId == null) + throw new System.ArgumentNullException("destinationFolderId"); + + 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(); + + // Operation Path: "queryProductOrder3" + urlBuilder_.Append("queryProductOrder3"); + urlBuilder_.Append('?'); + if (orderStatus != null) + { + foreach (var item_ in orderStatus) + { + urlBuilder_.Append(System.Uri.EscapeDataString("orderStatus")).Append('='); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } + } + foreach (var item_ in destinationFolderId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("destinationFolderId")).Append('='); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(item_, 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); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + 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 enum Anonymous + { + + [System.Runtime.Serialization.EnumMember(Value = @"Draft")] + Draft = 0, + + [System.Runtime.Serialization.EnumMember(Value = @"Submitted")] + Submitted = 1, + + [System.Runtime.Serialization.EnumMember(Value = @"Running")] + Running = 2, + + [System.Runtime.Serialization.EnumMember(Value = @"Completed")] + Completed = 3, + + [System.Runtime.Serialization.EnumMember(Value = @"Cancelled")] + Cancelled = 4, + + [System.Runtime.Serialization.EnumMember(Value = @"In Error")] + In_Error = 5, + + [System.Runtime.Serialization.EnumMember(Value = @"Suspended")] + Suspended = 6, + + [System.Runtime.Serialization.EnumMember(Value = @"Order Configuration Queued")] + Order_Configuration_Queued = 7, + + } + + public enum Anonymous2 + { + + [System.Runtime.Serialization.EnumMember(Value = @"Draft")] + Draft = 0, + + [System.Runtime.Serialization.EnumMember(Value = @"Submitted")] + Submitted = 1, + + [System.Runtime.Serialization.EnumMember(Value = @"Running")] + Running = 2, + + [System.Runtime.Serialization.EnumMember(Value = @"Completed")] + Completed = 3, + + [System.Runtime.Serialization.EnumMember(Value = @"Cancelled")] + Cancelled = 4, + + [System.Runtime.Serialization.EnumMember(Value = @"In Error")] + In_Error = 5, + + [System.Runtime.Serialization.EnumMember(Value = @"Suspended")] + Suspended = 6, + + [System.Runtime.Serialization.EnumMember(Value = @"Order Configuration Queued")] + Order_Configuration_Queued = 7, + + } + + + + 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/IssueTests.Issue5260_compilation_error_in_query_string_deep_object_parameters.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/IssueTests.Issue5260_compilation_error_in_query_string_deep_object_parameters.verified.txt new file mode 100644 index 000000000..76775568d --- /dev/null +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/IssueTests.Issue5260_compilation_error_in_query_string_deep_object_parameters.verified.txt @@ -0,0 +1,599 @@ + + +namespace MyNamespace +{ + using System = global::System; + + public partial interface IClient + { + System.Threading.Tasks.Task GetOrder1Async(Params @params); + + System.Threading.Tasks.Task GetOrder1Async(Params @params, System.Threading.CancellationToken cancellationToken); + + System.Threading.Tasks.Task GetOrder2Async(Params2 @params); + + System.Threading.Tasks.Task GetOrder2Async(Params2 @params, System.Threading.CancellationToken cancellationToken); + + System.Threading.Tasks.Task GetOrder3Async(Params3 @params); + + System.Threading.Tasks.Task GetOrder3Async(Params3 @params, System.Threading.CancellationToken cancellationToken); + + } + + public partial class Client : IClient + { + 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 Client(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. + { + _httpClient = httpClient; + Initialize(); + } + + private static Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings() + { + var settings = new Newtonsoft.Json.JsonSerializerSettings(); + UpdateJsonSerializerSettings(settings); + return settings; + } + + 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 GetOrder1Async(Params @params) + { + return GetOrder1Async(@params, System.Threading.CancellationToken.None); + } + + public virtual async System.Threading.Tasks.Task GetOrder1Async(Params @params, System.Threading.CancellationToken cancellationToken) + { + if (@params == null) + throw new System.ArgumentNullException("@params"); + + 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(); + + // Operation Path: "queryProductOrder1" + urlBuilder_.Append("queryProductOrder1"); + urlBuilder_.Append('?'); + if (@params.DestinationFolderId != null) + { + urlBuilder_.Append(System.Uri.EscapeDataString("params[destinationFolderId]")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(@params.DestinationFolderId, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } + foreach (var item_ in @params.AdditionalProperties) + { + urlBuilder_.Append(System.Uri.EscapeDataString(item_.Key)).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_.Value, 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); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + 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 GetOrder2Async(Params2 @params) + { + return GetOrder2Async(@params, System.Threading.CancellationToken.None); + } + + public virtual async System.Threading.Tasks.Task GetOrder2Async(Params2 @params, 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(); + + // Operation Path: "queryProductOrder2" + urlBuilder_.Append("queryProductOrder2"); + urlBuilder_.Append('?'); + if (@params != null) + { + if (@params.OrderStatus != null) + { + urlBuilder_.Append(System.Uri.EscapeDataString("params[orderStatus]")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(@params.OrderStatus, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } + foreach (var item_ in @params.AdditionalProperties) + { + urlBuilder_.Append(System.Uri.EscapeDataString(item_.Key)).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_.Value, 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); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + 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 GetOrder3Async(Params3 @params) + { + return GetOrder3Async(@params, System.Threading.CancellationToken.None); + } + + public virtual async System.Threading.Tasks.Task GetOrder3Async(Params3 @params, System.Threading.CancellationToken cancellationToken) + { + if (@params == null) + throw new System.ArgumentNullException("@params"); + + 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(); + + // Operation Path: "queryProductOrder3" + urlBuilder_.Append("queryProductOrder3"); + urlBuilder_.Append('?'); + if (@params.OrderStatus != null) + { + urlBuilder_.Append(System.Uri.EscapeDataString("params[orderStatus]")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(@params.OrderStatus, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } + if (@params.DestinationFolderId != null) + { + urlBuilder_.Append(System.Uri.EscapeDataString("params[destinationFolderId]")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(@params.DestinationFolderId, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } + foreach (var item_ in @params.AdditionalProperties) + { + urlBuilder_.Append(System.Uri.EscapeDataString(item_.Key)).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_.Value, 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); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + 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 Params + { + + [Newtonsoft.Json.JsonProperty("destinationFolderId", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string DestinationFolderId { get; set; } + + private System.Collections.Generic.IDictionary _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + public partial class Params2 + { + + [Newtonsoft.Json.JsonProperty("orderStatus", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] + public Params2OrderStatus OrderStatus { get; set; } + + private System.Collections.Generic.IDictionary _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + public partial class Params3 + { + + [Newtonsoft.Json.JsonProperty("orderStatus", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] + public Params3OrderStatus OrderStatus { get; set; } + + [Newtonsoft.Json.JsonProperty("destinationFolderId", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string DestinationFolderId { get; set; } + + private System.Collections.Generic.IDictionary _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + public enum Params2OrderStatus + { + + [System.Runtime.Serialization.EnumMember(Value = @"Draft")] + Draft = 0, + + [System.Runtime.Serialization.EnumMember(Value = @"Submitted")] + Submitted = 1, + + [System.Runtime.Serialization.EnumMember(Value = @"Running")] + Running = 2, + + [System.Runtime.Serialization.EnumMember(Value = @"Completed")] + Completed = 3, + + [System.Runtime.Serialization.EnumMember(Value = @"Cancelled")] + Cancelled = 4, + + [System.Runtime.Serialization.EnumMember(Value = @"In Error")] + In_Error = 5, + + [System.Runtime.Serialization.EnumMember(Value = @"Suspended")] + Suspended = 6, + + [System.Runtime.Serialization.EnumMember(Value = @"Order Configuration Queued")] + Order_Configuration_Queued = 7, + + } + + public enum Params3OrderStatus + { + + [System.Runtime.Serialization.EnumMember(Value = @"Draft")] + Draft = 0, + + [System.Runtime.Serialization.EnumMember(Value = @"Submitted")] + Submitted = 1, + + [System.Runtime.Serialization.EnumMember(Value = @"Running")] + Running = 2, + + [System.Runtime.Serialization.EnumMember(Value = @"Completed")] + Completed = 3, + + [System.Runtime.Serialization.EnumMember(Value = @"Cancelled")] + Cancelled = 4, + + [System.Runtime.Serialization.EnumMember(Value = @"In Error")] + In_Error = 5, + + [System.Runtime.Serialization.EnumMember(Value = @"Suspended")] + Suspended = 6, + + [System.Runtime.Serialization.EnumMember(Value = @"Order Configuration Queued")] + Order_Configuration_Queued = 7, + + } + + + + 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/IssueTests.Issue5260_compilation_error_in_query_string_dictionary_parameters.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/IssueTests.Issue5260_compilation_error_in_query_string_dictionary_parameters.verified.txt new file mode 100644 index 000000000..0669500d2 --- /dev/null +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/IssueTests.Issue5260_compilation_error_in_query_string_dictionary_parameters.verified.txt @@ -0,0 +1,297 @@ + + +namespace MyNamespace +{ + using System = global::System; + + public partial interface IClient + { + System.Threading.Tasks.Task> GetDynamicQueryAsync(System.Collections.Generic.IDictionary @params); + + System.Threading.Tasks.Task> GetDynamicQueryAsync(System.Collections.Generic.IDictionary @params, System.Threading.CancellationToken cancellationToken); + + } + + public partial class Client : IClient + { + 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 Client(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. + { + _httpClient = httpClient; + Initialize(); + } + + private static Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings() + { + var settings = new Newtonsoft.Json.JsonSerializerSettings(); + UpdateJsonSerializerSettings(settings); + return settings; + } + + 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> GetDynamicQueryAsync(System.Collections.Generic.IDictionary @params) + { + return GetDynamicQueryAsync(@params, System.Threading.CancellationToken.None); + } + + public virtual async System.Threading.Tasks.Task> GetDynamicQueryAsync(System.Collections.Generic.IDictionary @params, 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(); + + // Operation Path: "dynamicQuery" + urlBuilder_.Append("dynamicQuery"); + urlBuilder_.Append('?'); + if (@params != null) + { + foreach (var item_ in @params) + { + urlBuilder_.Append(System.Uri.EscapeDataString(item_.Key)).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_.Value, 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); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + 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/JIRA_OpenAPI.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/JIRA_OpenAPI.verified.txt index 3801489d0..14f7a4c51 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/JIRA_OpenAPI.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/JIRA_OpenAPI.verified.txt @@ -318,11 +318,17 @@ namespace MyNamespace urlBuilder_.Append('?'); if (id != null) { - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (fieldContextId != null) { - foreach (var item_ in fieldContextId) { urlBuilder_.Append(System.Uri.EscapeDataString("fieldContextId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in fieldContextId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("fieldContextId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (issueId != null) { @@ -588,11 +594,17 @@ namespace MyNamespace urlBuilder_.Append('?'); if (id != null) { - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (fieldContextId != null) { - foreach (var item_ in fieldContextId) { urlBuilder_.Append(System.Uri.EscapeDataString("fieldContextId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in fieldContextId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("fieldContextId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (issueId != null) { @@ -3819,7 +3831,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (status != null) { - foreach (var item_ in status) { urlBuilder_.Append(System.Uri.EscapeDataString("status")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in status) + { + urlBuilder_.Append(System.Uri.EscapeDataString("status")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (orderBy != null) { @@ -4520,7 +4535,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (projectIdsOrKeys != null) { - foreach (var item_ in projectIdsOrKeys) { urlBuilder_.Append(System.Uri.EscapeDataString("projectIdsOrKeys")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in projectIdsOrKeys) + { + urlBuilder_.Append(System.Uri.EscapeDataString("projectIdsOrKeys")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (startAt != null) { @@ -6489,15 +6507,24 @@ namespace MyNamespace urlBuilder_.Append('?'); if (moduleKey != null) { - foreach (var item_ in moduleKey) { urlBuilder_.Append(System.Uri.EscapeDataString("moduleKey")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in moduleKey) + { + urlBuilder_.Append(System.Uri.EscapeDataString("moduleKey")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (uri != null) { - foreach (var item_ in uri) { urlBuilder_.Append(System.Uri.EscapeDataString("uri")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in uri) + { + urlBuilder_.Append(System.Uri.EscapeDataString("uri")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (gadgetId != null) { - foreach (var item_ in gadgetId) { urlBuilder_.Append(System.Uri.EscapeDataString("gadgetId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in gadgetId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("gadgetId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; @@ -9129,11 +9156,17 @@ namespace MyNamespace } if (type != null) { - foreach (var item_ in type) { urlBuilder_.Append(System.Uri.EscapeDataString("type")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in type) + { + urlBuilder_.Append(System.Uri.EscapeDataString("type")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (id != null) { - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (query != null) { @@ -9149,7 +9182,10 @@ namespace MyNamespace } if (projectIds != null) { - foreach (var item_ in projectIds) { urlBuilder_.Append(System.Uri.EscapeDataString("projectIds")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in projectIds) + { + urlBuilder_.Append(System.Uri.EscapeDataString("projectIds")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; @@ -9278,7 +9314,10 @@ namespace MyNamespace } if (id != null) { - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (query != null) { @@ -9541,7 +9580,10 @@ namespace MyNamespace } if (contextId != null) { - foreach (var item_ in contextId) { urlBuilder_.Append(System.Uri.EscapeDataString("contextId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in contextId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("contextId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (startAt != null) { @@ -9811,7 +9853,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (contextId != null) { - foreach (var item_ in contextId) { urlBuilder_.Append(System.Uri.EscapeDataString("contextId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in contextId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("contextId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (startAt != null) { @@ -10080,7 +10125,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (contextId != null) { - foreach (var item_ in contextId) { urlBuilder_.Append(System.Uri.EscapeDataString("contextId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in contextId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("contextId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (startAt != null) { @@ -10329,7 +10377,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (contextId != null) { - foreach (var item_ in contextId) { urlBuilder_.Append(System.Uri.EscapeDataString("contextId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in contextId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("contextId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (startAt != null) { @@ -13544,7 +13595,10 @@ namespace MyNamespace } if (id != null) { - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (isDefault != null) { @@ -14232,7 +14286,10 @@ namespace MyNamespace } if (id != null) { - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; @@ -14455,7 +14512,10 @@ namespace MyNamespace } if (fieldConfigurationSchemeId != null) { - foreach (var item_ in fieldConfigurationSchemeId) { urlBuilder_.Append(System.Uri.EscapeDataString("fieldConfigurationSchemeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in fieldConfigurationSchemeId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("fieldConfigurationSchemeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; @@ -14572,7 +14632,10 @@ namespace MyNamespace // Operation Path: "rest/api/3/fieldconfigurationscheme/project" urlBuilder_.Append("rest/api/3/fieldconfigurationscheme/project"); urlBuilder_.Append('?'); - foreach (var item_ in projectId) { urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in projectId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } if (startAt != null) { urlBuilder_.Append(System.Uri.EscapeDataString("startAt")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(startAt, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); @@ -15854,7 +15917,10 @@ namespace MyNamespace } if (id != null) { - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (orderBy != null) { @@ -17738,11 +17804,17 @@ namespace MyNamespace } if (groupId != null) { - foreach (var item_ in groupId) { urlBuilder_.Append(System.Uri.EscapeDataString("groupId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in groupId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("groupId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (groupName != null) { - foreach (var item_ in groupName) { urlBuilder_.Append(System.Uri.EscapeDataString("groupName")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in groupName) + { + urlBuilder_.Append(System.Uri.EscapeDataString("groupName")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (accessType != null) { @@ -18269,11 +18341,17 @@ namespace MyNamespace } if (exclude != null) { - foreach (var item_ in exclude) { urlBuilder_.Append(System.Uri.EscapeDataString("exclude")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in exclude) + { + urlBuilder_.Append(System.Uri.EscapeDataString("exclude")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (excludeId != null) { - foreach (var item_ in excludeId) { urlBuilder_.Append(System.Uri.EscapeDataString("excludeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in excludeId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("excludeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (maxResults != null) { @@ -18415,11 +18493,17 @@ namespace MyNamespace } if (projectId != null) { - foreach (var item_ in projectId) { urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in projectId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (issueTypeId != null) { - foreach (var item_ in issueTypeId) { urlBuilder_.Append(System.Uri.EscapeDataString("issueTypeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in issueTypeId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("issueTypeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (avatarSize != null) { @@ -19248,19 +19332,31 @@ namespace MyNamespace urlBuilder_.Append('?'); if (projectIds != null) { - foreach (var item_ in projectIds) { urlBuilder_.Append(System.Uri.EscapeDataString("projectIds")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in projectIds) + { + urlBuilder_.Append(System.Uri.EscapeDataString("projectIds")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (projectKeys != null) { - foreach (var item_ in projectKeys) { urlBuilder_.Append(System.Uri.EscapeDataString("projectKeys")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in projectKeys) + { + urlBuilder_.Append(System.Uri.EscapeDataString("projectKeys")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (issuetypeIds != null) { - foreach (var item_ in issuetypeIds) { urlBuilder_.Append(System.Uri.EscapeDataString("issuetypeIds")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in issuetypeIds) + { + urlBuilder_.Append(System.Uri.EscapeDataString("issuetypeIds")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (issuetypeNames != null) { - foreach (var item_ in issuetypeNames) { urlBuilder_.Append(System.Uri.EscapeDataString("issuetypeNames")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in issuetypeNames) + { + urlBuilder_.Append(System.Uri.EscapeDataString("issuetypeNames")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (expand != null) { @@ -20710,7 +20806,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (fields != null) { - foreach (var item_ in fields) { urlBuilder_.Append(System.Uri.EscapeDataString("fields")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in fields) + { + urlBuilder_.Append(System.Uri.EscapeDataString("fields")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (fieldsByKeys != null) { @@ -20722,7 +20821,10 @@ namespace MyNamespace } if (properties != null) { - foreach (var item_ in properties) { urlBuilder_.Append(System.Uri.EscapeDataString("properties")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in properties) + { + urlBuilder_.Append(System.Uri.EscapeDataString("properties")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (updateHistory != null) { @@ -27275,11 +27377,17 @@ namespace MyNamespace } if (id != null) { - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (schemeId != null) { - foreach (var item_ in schemeId) { urlBuilder_.Append(System.Uri.EscapeDataString("schemeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in schemeId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("schemeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (onlyDefault != null) { @@ -27548,15 +27656,24 @@ namespace MyNamespace } if (id != null) { - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (schemeId != null) { - foreach (var item_ in schemeId) { urlBuilder_.Append(System.Uri.EscapeDataString("schemeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in schemeId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("schemeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (levelId != null) { - foreach (var item_ in levelId) { urlBuilder_.Append(System.Uri.EscapeDataString("levelId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in levelId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("levelId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (expand != null) { @@ -27673,11 +27790,17 @@ namespace MyNamespace } if (issueSecuritySchemeId != null) { - foreach (var item_ in issueSecuritySchemeId) { urlBuilder_.Append(System.Uri.EscapeDataString("issueSecuritySchemeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in issueSecuritySchemeId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("issueSecuritySchemeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (projectId != null) { - foreach (var item_ in projectId) { urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in projectId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; @@ -27950,11 +28073,17 @@ namespace MyNamespace } if (id != null) { - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (projectId != null) { - foreach (var item_ in projectId) { urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in projectId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; @@ -28313,7 +28442,10 @@ namespace MyNamespace } if (issueSecurityLevelId != null) { - foreach (var item_ in issueSecurityLevelId) { urlBuilder_.Append(System.Uri.EscapeDataString("issueSecurityLevelId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in issueSecurityLevelId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("issueSecurityLevelId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (expand != null) { @@ -30611,7 +30743,10 @@ namespace MyNamespace } if (id != null) { - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (orderBy != null) { @@ -30849,7 +30984,10 @@ namespace MyNamespace } if (issueTypeSchemeId != null) { - foreach (var item_ in issueTypeSchemeId) { urlBuilder_.Append(System.Uri.EscapeDataString("issueTypeSchemeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in issueTypeSchemeId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("issueTypeSchemeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; @@ -30958,7 +31096,10 @@ namespace MyNamespace // Operation Path: "rest/api/3/issuetypescheme/project" urlBuilder_.Append("rest/api/3/issuetypescheme/project"); urlBuilder_.Append('?'); - foreach (var item_ in projectId) { urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in projectId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } if (startAt != null) { urlBuilder_.Append(System.Uri.EscapeDataString("startAt")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(startAt, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); @@ -31790,7 +31931,10 @@ namespace MyNamespace } if (id != null) { - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (queryString != null) { @@ -32035,7 +32179,10 @@ namespace MyNamespace } if (issueTypeScreenSchemeId != null) { - foreach (var item_ in issueTypeScreenSchemeId) { urlBuilder_.Append(System.Uri.EscapeDataString("issueTypeScreenSchemeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in issueTypeScreenSchemeId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("issueTypeScreenSchemeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; @@ -32144,7 +32291,10 @@ namespace MyNamespace // Operation Path: "rest/api/3/issuetypescreenscheme/project" urlBuilder_.Append("rest/api/3/issuetypescreenscheme/project"); urlBuilder_.Append('?'); - foreach (var item_ in projectId) { urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in projectId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } if (startAt != null) { urlBuilder_.Append(System.Uri.EscapeDataString("startAt")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(startAt, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); @@ -33392,7 +33542,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (functionKey != null) { - foreach (var item_ in functionKey) { urlBuilder_.Append(System.Uri.EscapeDataString("functionKey")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in functionKey) + { + urlBuilder_.Append(System.Uri.EscapeDataString("functionKey")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (startAt != null) { @@ -35403,11 +35556,17 @@ namespace MyNamespace } if (id != null) { - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (projectId != null) { - foreach (var item_ in projectId) { urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in projectId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (onlyDefault != null) { @@ -35640,11 +35799,17 @@ namespace MyNamespace } if (notificationSchemeId != null) { - foreach (var item_ in notificationSchemeId) { urlBuilder_.Append(System.Uri.EscapeDataString("notificationSchemeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in notificationSchemeId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("notificationSchemeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (projectId != null) { - foreach (var item_ in projectId) { urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in projectId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; @@ -40475,11 +40640,17 @@ namespace MyNamespace } if (id != null) { - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (projectId != null) { - foreach (var item_ in projectId) { urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in projectId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (priorityName != null) { @@ -40975,11 +41146,17 @@ namespace MyNamespace } if (priorityId != null) { - foreach (var item_ in priorityId) { urlBuilder_.Append(System.Uri.EscapeDataString("priorityId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in priorityId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("priorityId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (schemeId != null) { - foreach (var item_ in schemeId) { urlBuilder_.Append(System.Uri.EscapeDataString("schemeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in schemeId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("schemeId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (schemeName != null) { @@ -41331,7 +41508,10 @@ namespace MyNamespace } if (exclude != null) { - foreach (var item_ in exclude) { urlBuilder_.Append(System.Uri.EscapeDataString("exclude")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in exclude) + { + urlBuilder_.Append(System.Uri.EscapeDataString("exclude")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; @@ -41774,7 +41954,10 @@ namespace MyNamespace } if (projectId != null) { - foreach (var item_ in projectId) { urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in projectId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (query != null) { @@ -41894,7 +42077,10 @@ namespace MyNamespace } if (properties != null) { - foreach (var item_ in properties) { urlBuilder_.Append(System.Uri.EscapeDataString("properties")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in properties) + { + urlBuilder_.Append(System.Uri.EscapeDataString("properties")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; @@ -42227,7 +42413,10 @@ namespace MyNamespace } if (properties != null) { - foreach (var item_ in properties) { urlBuilder_.Append(System.Uri.EscapeDataString("properties")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in properties) + { + urlBuilder_.Append(System.Uri.EscapeDataString("properties")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; @@ -42387,11 +42576,17 @@ namespace MyNamespace } if (id != null) { - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (keys != null) { - foreach (var item_ in keys) { urlBuilder_.Append(System.Uri.EscapeDataString("keys")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in keys) + { + urlBuilder_.Append(System.Uri.EscapeDataString("keys")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (query != null) { @@ -42415,11 +42610,17 @@ namespace MyNamespace } if (status != null) { - foreach (var item_ in status) { urlBuilder_.Append(System.Uri.EscapeDataString("status")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in status) + { + urlBuilder_.Append(System.Uri.EscapeDataString("status")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (properties != null) { - foreach (var item_ in properties) { urlBuilder_.Append(System.Uri.EscapeDataString("properties")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in properties) + { + urlBuilder_.Append(System.Uri.EscapeDataString("properties")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (propertyQuery != null) { @@ -43003,7 +43204,10 @@ namespace MyNamespace } if (properties != null) { - foreach (var item_ in properties) { urlBuilder_.Append(System.Uri.EscapeDataString("properties")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in properties) + { + urlBuilder_.Append(System.Uri.EscapeDataString("properties")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; @@ -48463,7 +48667,10 @@ namespace MyNamespace } if (id != null) { - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (onlyDefault != null) { @@ -49976,7 +50183,10 @@ namespace MyNamespace } if (id != null) { - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (queryString != null) { @@ -49984,7 +50194,10 @@ namespace MyNamespace } if (scope != null) { - foreach (var item_ in scope) { urlBuilder_.Append(System.Uri.EscapeDataString("scope")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in scope) + { + urlBuilder_.Append(System.Uri.EscapeDataString("scope")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (orderBy != null) { @@ -50304,11 +50517,17 @@ namespace MyNamespace urlBuilder_.Append('?'); if (screenId != null) { - foreach (var item_ in screenId) { urlBuilder_.Append(System.Uri.EscapeDataString("screenId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in screenId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("screenId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (tabId != null) { - foreach (var item_ in tabId) { urlBuilder_.Append(System.Uri.EscapeDataString("tabId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in tabId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("tabId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (startAt != null) { @@ -51817,7 +52036,10 @@ namespace MyNamespace } if (id != null) { - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (expand != null) { @@ -52324,7 +52546,10 @@ namespace MyNamespace } if (fields != null) { - foreach (var item_ in fields) { urlBuilder_.Append(System.Uri.EscapeDataString("fields")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in fields) + { + urlBuilder_.Append(System.Uri.EscapeDataString("fields")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (expand != null) { @@ -52332,7 +52557,10 @@ namespace MyNamespace } if (properties != null) { - foreach (var item_ in properties) { urlBuilder_.Append(System.Uri.EscapeDataString("properties")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in properties) + { + urlBuilder_.Append(System.Uri.EscapeDataString("properties")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (fieldsByKeys != null) { @@ -52816,7 +53044,10 @@ namespace MyNamespace } if (fields != null) { - foreach (var item_ in fields) { urlBuilder_.Append(System.Uri.EscapeDataString("fields")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in fields) + { + urlBuilder_.Append(System.Uri.EscapeDataString("fields")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (expand != null) { @@ -52824,7 +53055,10 @@ namespace MyNamespace } if (properties != null) { - foreach (var item_ in properties) { urlBuilder_.Append(System.Uri.EscapeDataString("properties")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in properties) + { + urlBuilder_.Append(System.Uri.EscapeDataString("properties")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (fieldsByKeys != null) { @@ -52836,7 +53070,10 @@ namespace MyNamespace } if (reconcileIssues != null) { - foreach (var item_ in reconcileIssues) { urlBuilder_.Append(System.Uri.EscapeDataString("reconcileIssues")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in reconcileIssues) + { + urlBuilder_.Append(System.Uri.EscapeDataString("reconcileIssues")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; @@ -53808,7 +54045,10 @@ namespace MyNamespace // Operation Path: "rest/api/3/statuses" urlBuilder_.Append("rest/api/3/statuses"); urlBuilder_.Append('?'); - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } urlBuilder_.Length--; PrepareRequest(client_, request_, urlBuilder_); @@ -53917,7 +54157,10 @@ namespace MyNamespace // Operation Path: "rest/api/3/statuses" urlBuilder_.Append("rest/api/3/statuses"); urlBuilder_.Append('?'); - foreach (var item_ in id) { urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in id) + { + urlBuilder_.Append(System.Uri.EscapeDataString("id")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } if (expand != null) { urlBuilder_.Append(System.Uri.EscapeDataString("expand")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(expand, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); @@ -56891,7 +57134,10 @@ namespace MyNamespace // Operation Path: "rest/api/3/user/bulk" urlBuilder_.Append("rest/api/3/user/bulk"); urlBuilder_.Append('?'); - foreach (var item_ in accountId) { urlBuilder_.Append(System.Uri.EscapeDataString("accountId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in accountId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("accountId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } if (startAt != null) { urlBuilder_.Append(System.Uri.EscapeDataString("startAt")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(startAt, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); @@ -56902,11 +57148,17 @@ namespace MyNamespace } if (username != null) { - foreach (var item_ in username) { urlBuilder_.Append(System.Uri.EscapeDataString("username")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in username) + { + urlBuilder_.Append(System.Uri.EscapeDataString("username")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (key != null) { - foreach (var item_ in key) { urlBuilder_.Append(System.Uri.EscapeDataString("key")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in key) + { + urlBuilder_.Append(System.Uri.EscapeDataString("key")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; @@ -57015,11 +57267,17 @@ namespace MyNamespace } if (username != null) { - foreach (var item_ in username) { urlBuilder_.Append(System.Uri.EscapeDataString("username")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in username) + { + urlBuilder_.Append(System.Uri.EscapeDataString("username")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (key != null) { - foreach (var item_ in key) { urlBuilder_.Append(System.Uri.EscapeDataString("key")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in key) + { + urlBuilder_.Append(System.Uri.EscapeDataString("key")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; @@ -57567,7 +57825,10 @@ namespace MyNamespace // Operation Path: "rest/api/3/user/email/bulk" urlBuilder_.Append("rest/api/3/user/email/bulk"); urlBuilder_.Append('?'); - foreach (var item_ in accountId) { urlBuilder_.Append(System.Uri.EscapeDataString("accountId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in accountId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("accountId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } urlBuilder_.Length--; PrepareRequest(client_, request_, urlBuilder_); @@ -58260,11 +58521,17 @@ namespace MyNamespace } if (exclude != null) { - foreach (var item_ in exclude) { urlBuilder_.Append(System.Uri.EscapeDataString("exclude")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in exclude) + { + urlBuilder_.Append(System.Uri.EscapeDataString("exclude")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (excludeAccountIds != null) { - foreach (var item_ in excludeAccountIds) { urlBuilder_.Append(System.Uri.EscapeDataString("excludeAccountIds")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in excludeAccountIds) + { + urlBuilder_.Append(System.Uri.EscapeDataString("excludeAccountIds")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (avatarSize != null) { @@ -62652,7 +62919,10 @@ namespace MyNamespace // Operation Path: "rest/api/3/workflow/rule/config" urlBuilder_.Append("rest/api/3/workflow/rule/config"); urlBuilder_.Append('?'); - foreach (var item_ in types) { urlBuilder_.Append(System.Uri.EscapeDataString("types")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in types) + { + urlBuilder_.Append(System.Uri.EscapeDataString("types")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } if (startAt != null) { urlBuilder_.Append(System.Uri.EscapeDataString("startAt")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(startAt, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); @@ -62663,15 +62933,24 @@ namespace MyNamespace } if (keys != null) { - foreach (var item_ in keys) { urlBuilder_.Append(System.Uri.EscapeDataString("keys")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in keys) + { + urlBuilder_.Append(System.Uri.EscapeDataString("keys")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (workflowNames != null) { - foreach (var item_ in workflowNames) { urlBuilder_.Append(System.Uri.EscapeDataString("workflowNames")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in workflowNames) + { + urlBuilder_.Append(System.Uri.EscapeDataString("workflowNames")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (withTags != null) { - foreach (var item_ in withTags) { urlBuilder_.Append(System.Uri.EscapeDataString("withTags")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in withTags) + { + urlBuilder_.Append(System.Uri.EscapeDataString("withTags")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (draft != null) { @@ -63065,7 +63344,10 @@ namespace MyNamespace } if (workflowName != null) { - foreach (var item_ in workflowName) { urlBuilder_.Append(System.Uri.EscapeDataString("workflowName")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in workflowName) + { + urlBuilder_.Append(System.Uri.EscapeDataString("workflowName")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (expand != null) { @@ -65690,7 +65972,10 @@ namespace MyNamespace // Operation Path: "rest/api/3/workflowscheme/project" urlBuilder_.Append("rest/api/3/workflowscheme/project"); urlBuilder_.Append('?'); - foreach (var item_ in projectId) { urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in projectId) + { + urlBuilder_.Append(System.Uri.EscapeDataString("projectId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } urlBuilder_.Length--; PrepareRequest(client_, request_, urlBuilder_); @@ -71213,7 +71498,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (moduleKey != null) { - foreach (var item_ in moduleKey) { urlBuilder_.Append(System.Uri.EscapeDataString("moduleKey")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in moduleKey) + { + urlBuilder_.Append(System.Uri.EscapeDataString("moduleKey")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; @@ -72873,7 +73161,10 @@ namespace MyNamespace // Operation Path: "rest/atlassian-connect/1/service-registry" urlBuilder_.Append("rest/atlassian-connect/1/service-registry"); urlBuilder_.Append('?'); - foreach (var item_ in serviceIds) { urlBuilder_.Append(System.Uri.EscapeDataString("serviceIds")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in serviceIds) + { + urlBuilder_.Append(System.Uri.EscapeDataString("serviceIds")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } urlBuilder_.Length--; PrepareRequest(client_, request_, urlBuilder_); diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ParameterTests.Deep_object_properties_are_correctly_named.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ParameterTests.Deep_object_properties_are_correctly_named.verified.txt index 0455fff5c..93bd16501 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ParameterTests.Deep_object_properties_are_correctly_named.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ParameterTests.Deep_object_properties_are_correctly_named.verified.txt @@ -97,7 +97,10 @@ namespace MyNamespace { urlBuilder_.Append(System.Uri.EscapeDataString("options[optionalOriginLocationCode]")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(options.OptionalOriginLocationCode, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } - foreach (var item_ in options.AdditionalProperties) { urlBuilder_.Append(System.Uri.EscapeDataString(item_.Key)).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_.Value, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in options.AdditionalProperties) + { + urlBuilder_.Append(System.Uri.EscapeDataString(item_.Key)).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_.Value, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ParameterTests.When_parameter_is_array_and_should_not_be_exploded.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ParameterTests.When_parameter_is_array_and_should_not_be_exploded.verified.txt index 636ca74f1..579697b08 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ParameterTests.When_parameter_is_array_and_should_not_be_exploded.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ParameterTests.When_parameter_is_array_and_should_not_be_exploded.verified.txt @@ -73,20 +73,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (bar != null) { - bool isAfterFirst = false; foreach (var item_ in bar) { - if (!isAfterFirst) - { - urlBuilder_.Append(System.Uri.EscapeDataString("foo")).Append('='); - } - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append(','); - isAfterFirst = true; - } - if (isAfterFirst) - { - urlBuilder_.Length--; - urlBuilder_.Append('&'); + urlBuilder_.Append(System.Uri.EscapeDataString("foo")).Append('='); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } } urlBuilder_.Length--; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ParameterTests.When_parent_parameters_have_same_kind_then_they_are_included.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ParameterTests.When_parent_parameters_have_same_kind_then_they_are_included.verified.txt index 13f89b8f0..c96e39694 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ParameterTests.When_parent_parameters_have_same_kind_then_they_are_included.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ParameterTests.When_parent_parameters_have_same_kind_then_they_are_included.verified.txt @@ -81,20 +81,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (elementId != null) { - bool isAfterFirst = false; foreach (var item_ in elementId) { - if (!isAfterFirst) - { - urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('='); - } - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append(','); - isAfterFirst = true; - } - if (isAfterFirst) - { - urlBuilder_.Length--; - urlBuilder_.Append('&'); + urlBuilder_.Append(System.Uri.EscapeDataString("elementId")).Append('='); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } } urlBuilder_.Length--; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/QueryParameterTests.When_query_parameter_is_mixed_free_form_object_parameters_are_expanded.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/QueryParameterTests.When_query_parameter_is_mixed_free_form_object_parameters_are_expanded.verified.txt index be9406fcf..494cd3b3b 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/QueryParameterTests.When_query_parameter_is_mixed_free_form_object_parameters_are_expanded.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/QueryParameterTests.When_query_parameter_is_mixed_free_form_object_parameters_are_expanded.verified.txt @@ -81,7 +81,10 @@ namespace MyNamespace { urlBuilder_.Append(System.Uri.EscapeDataString("default")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(extendedProperties.Default, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } - foreach (var item_ in extendedProperties.AdditionalProperties) { urlBuilder_.Append(System.Uri.EscapeDataString(item_.Key)).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_.Value, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in extendedProperties.AdditionalProperties) + { + urlBuilder_.Append(System.Uri.EscapeDataString(item_.Key)).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_.Value, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/QueryParameterTests.When_query_parameter_is_set_to_explode_and_style_is_form_object_parameters_are_expanded.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/QueryParameterTests.When_query_parameter_is_set_to_explode_and_style_is_form_object_parameters_are_expanded.verified.txt index 7b7683fe3..c52f4b7f2 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/QueryParameterTests.When_query_parameter_is_set_to_explode_and_style_is_form_object_parameters_are_expanded.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/QueryParameterTests.When_query_parameter_is_set_to_explode_and_style_is_form_object_parameters_are_expanded.verified.txt @@ -81,7 +81,10 @@ namespace MyNamespace { urlBuilder_.Append(System.Uri.EscapeDataString("limit")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(paging.Limit, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } - foreach (var item_ in paging.AdditionalProperties) { urlBuilder_.Append(System.Uri.EscapeDataString(item_.Key)).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_.Value, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in paging.AdditionalProperties) + { + urlBuilder_.Append(System.Uri.EscapeDataString(item_.Key)).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_.Value, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/QueryParameterTests.When_query_parameter_is_typed_free_form_object_parameters_are_expanded.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/QueryParameterTests.When_query_parameter_is_typed_free_form_object_parameters_are_expanded.verified.txt index 044307c0f..346386465 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/QueryParameterTests.When_query_parameter_is_typed_free_form_object_parameters_are_expanded.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/QueryParameterTests.When_query_parameter_is_typed_free_form_object_parameters_are_expanded.verified.txt @@ -73,7 +73,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (extendedProperties != null) { - foreach (var item_ in extendedProperties) { urlBuilder_.Append(System.Uri.EscapeDataString(item_.Key)).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_.Value, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in extendedProperties) + { + urlBuilder_.Append(System.Uri.EscapeDataString(item_.Key)).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_.Value, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/QueryParameterTests.When_query_parameter_is_untyped_free_form_object_parameters_are_expanded.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/QueryParameterTests.When_query_parameter_is_untyped_free_form_object_parameters_are_expanded.verified.txt index 5e310dfe1..334510039 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/QueryParameterTests.When_query_parameter_is_untyped_free_form_object_parameters_are_expanded.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/QueryParameterTests.When_query_parameter_is_untyped_free_form_object_parameters_are_expanded.verified.txt @@ -73,7 +73,10 @@ namespace MyNamespace urlBuilder_.Append('?'); if (extendedProperties != null) { - foreach (var item_ in extendedProperties.AdditionalProperties) { urlBuilder_.Append(System.Uri.EscapeDataString(item_.Key)).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_.Value, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in extendedProperties.AdditionalProperties) + { + urlBuilder_.Append(System.Uri.EscapeDataString(item_.Key)).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_.Value, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } urlBuilder_.Length--; diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ShipBob_OpenAPI.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ShipBob_OpenAPI.verified.txt index 7acf0d9cc..b10a3fcba 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ShipBob_OpenAPI.verified.txt +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/ShipBob_OpenAPI.verified.txt @@ -6336,7 +6336,10 @@ namespace MyNamespace } if (invoiceTypes != null) { - foreach (var item_ in invoiceTypes) { urlBuilder_.Append(System.Uri.EscapeDataString("InvoiceTypes")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } + foreach (var item_ in invoiceTypes) + { + urlBuilder_.Append(System.Uri.EscapeDataString("InvoiceTypes")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } } if (pageSize != null) { diff --git a/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/UseRequiredKeywordNewtonsoftJsonSchemaGeneratorTests.When_setting_is_enabled_properties_with_required_keyword_should_generate_with_required_keyword.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/UseRequiredKeywordNewtonsoftJsonSchemaGeneratorTests.When_setting_is_enabled_properties_with_required_keyword_should_generate_with_required_keyword.verified.txt new file mode 100644 index 000000000..a1205e8a6 --- /dev/null +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/UseRequiredKeywordNewtonsoftJsonSchemaGeneratorTests.When_setting_is_enabled_properties_with_required_keyword_should_generate_with_required_keyword.verified.txt @@ -0,0 +1,310 @@ + + +namespace MyNamespace +{ + using System = global::System; + + public partial class TestClient + { + #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 TestClient(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 TestWithInputAsync(DTOWithRequiredFieldsOfNewtonsoftJsonSchemaGeneratorSettings input) + { + return TestWithInputAsync(input, System.Threading.CancellationToken.None); + } + + public virtual async System.Threading.Tasks.Task TestWithInputAsync(DTOWithRequiredFieldsOfNewtonsoftJsonSchemaGeneratorSettings input, System.Threading.CancellationToken cancellationToken) + { + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(input, JsonSerializerSettings); + var content_ = new System.Net.Http.StringContent(json_); + content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json"); + request_.Content = content_; + request_.Method = new System.Net.Http.HttpMethod("POST"); + + var urlBuilder_ = new System.Text.StringBuilder(); + if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); + // Operation Path: "TestWithInput" + urlBuilder_.Append("TestWithInput"); + + 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_ == 204) + { + return; + } + 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 DTOWithRequiredFieldsOfNewtonsoftJsonSchemaGeneratorSettings + { + + [Newtonsoft.Json.JsonProperty("RequiredByAttribute", Required = Newtonsoft.Json.Required.Always)] + public required int RequiredByAttribute { get; set; } + + [Newtonsoft.Json.JsonProperty("RequiredByC11Keyword", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string RequiredByC11Keyword { get; set; } + + [Newtonsoft.Json.JsonProperty("RequiredByAttributeAndC11Keyword", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public required string RequiredByAttributeAndC11Keyword { get; set; } + + [Newtonsoft.Json.JsonProperty("NotRequired", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string NotRequired { get; set; } + + } + + + + 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/UseRequiredKeywordSystemTextJsonSchemaGeneratorSettingsTests.When_setting_is_enabled_properties_with_required_keyword_should_generate_with_required_keyword.verified.txt b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/UseRequiredKeywordSystemTextJsonSchemaGeneratorSettingsTests.When_setting_is_enabled_properties_with_required_keyword_should_generate_with_required_keyword.verified.txt new file mode 100644 index 000000000..1d8c4f248 --- /dev/null +++ b/src/NSwag.CodeGeneration.CSharp.Tests/Snapshots/UseRequiredKeywordSystemTextJsonSchemaGeneratorSettingsTests.When_setting_is_enabled_properties_with_required_keyword_should_generate_with_required_keyword.verified.txt @@ -0,0 +1,310 @@ + + +namespace MyNamespace +{ + using System = global::System; + + public partial class TestClient + { + #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 TestClient(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 TestWithInputAsync(DTOWithRequiredFieldsOfSystemTextJsonSchemaGeneratorSettings input) + { + return TestWithInputAsync(input, System.Threading.CancellationToken.None); + } + + public virtual async System.Threading.Tasks.Task TestWithInputAsync(DTOWithRequiredFieldsOfSystemTextJsonSchemaGeneratorSettings input, System.Threading.CancellationToken cancellationToken) + { + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(input, JsonSerializerSettings); + var content_ = new System.Net.Http.StringContent(json_); + content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json"); + request_.Content = content_; + request_.Method = new System.Net.Http.HttpMethod("POST"); + + var urlBuilder_ = new System.Text.StringBuilder(); + if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); + // Operation Path: "TestWithInput" + urlBuilder_.Append("TestWithInput"); + + 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_ == 204) + { + return; + } + 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 DTOWithRequiredFieldsOfSystemTextJsonSchemaGeneratorSettings + { + + [Newtonsoft.Json.JsonProperty("RequiredByAttribute", Required = Newtonsoft.Json.Required.Always)] + public required int RequiredByAttribute { get; set; } + + [Newtonsoft.Json.JsonProperty("RequiredByC11Keyword", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string RequiredByC11Keyword { get; set; } + + [Newtonsoft.Json.JsonProperty("RequiredByAttributeAndC11Keyword", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public required string RequiredByAttributeAndC11Keyword { get; set; } + + [Newtonsoft.Json.JsonProperty("NotRequired", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string NotRequired { get; set; } + + } + + + + 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/WrapResponsesTests.cs b/src/NSwag.CodeGeneration.CSharp.Tests/WrapResponsesTests.cs index 1a608deef..bbda51e53 100644 --- a/src/NSwag.CodeGeneration.CSharp.Tests/WrapResponsesTests.cs +++ b/src/NSwag.CodeGeneration.CSharp.Tests/WrapResponsesTests.cs @@ -63,6 +63,15 @@ public async Task When_success_responses_are_wrapped_then_SwaggerResponse_is_ret // Assert await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code + @" +namespace MyNamespace +{ + public static class Extensions + { + public static string[] ToArray(this object strings) { return new string[0]; } + } +} +"); } [Fact] @@ -85,6 +94,15 @@ public async Task When_success_responses_are_wrapped_then_SwaggerResponse_is_ret // Assert await VerifyHelper.Verify(code); + CSharpCompiler.AssertCompile(code + @" +namespace MyNamespace +{ + public static class Extensions + { + public static string[] ToArray(this object strings) { return new string[0]; } + } +} +"); } } } \ No newline at end of file diff --git a/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.PathParameter.liquid b/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.PathParameter.liquid index f23e576bc..63bc88457 100644 --- a/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.PathParameter.liquid +++ b/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.PathParameter.liquid @@ -1,21 +1,29 @@ {% if parameter.IsDateTimeArray -%} { - bool isAfterFirst = false; + var i = 0; foreach (var item in {{ parameter.VariableName }}) { - if (isAfterFirst) urlBuilder_.Append(','); urlBuilder_.Append(System.Uri.EscapeDataString(item.ToString("{{ ParameterDateTimeFormat }}", System.Globalization.CultureInfo.InvariantCulture))); - isAfterFirst = true; + urlBuilder_.Append(','); + i++; + } + if (i > 0) + { + urlBuilder_.Length--; } } {% elsif parameter.IsDateArray -%} { - bool isAfterFirst = false; + var i = 0; foreach (var item in {{ parameter.VariableName }}) { - if (isAfterFirst) urlBuilder_.Append(','); urlBuilder_.Append(System.Uri.EscapeDataString(item.ToString("{{ ParameterDateFormat }}", System.Globalization.CultureInfo.InvariantCulture))); - isAfterFirst = true; + urlBuilder_.Append(','); + i++; + } + if (i > 0) + { + urlBuilder_.Length--; } } {% elsif parameter.IsDateTime -%} @@ -24,12 +32,16 @@ urlBuilder_.Append(System.Uri.EscapeDataString({{ parameter.VariableName }}.ToSt urlBuilder_.Append(System.Uri.EscapeDataString({{ parameter.VariableName }}.ToString("{{ ParameterDateFormat }}", System.Globalization.CultureInfo.InvariantCulture))); {% elsif parameter.IsArray -%} { - bool isAfterFirst = false; + var i = 0; foreach (var item in {{ parameter.VariableName }}) { - if (isAfterFirst) urlBuilder_.Append(','); - urlBuilder_.Append(ConvertToString(item, System.Globalization.CultureInfo.InvariantCulture)); - isAfterFirst = true; + urlBuilder_.Append(System.Uri.EscapeDataString(item, System.Globalization.CultureInfo.InvariantCulture)); + urlBuilder_.Append(','); + i++; + } + if (i > 0) + { + urlBuilder_.Length--; } } {% else -%} diff --git a/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.QueryParameter.liquid b/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.QueryParameter.liquid index 650bbb688..5bdc9f532 100644 --- a/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.QueryParameter.liquid +++ b/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.QueryParameter.liquid @@ -1,43 +1,45 @@ {% if parameter.IsDateTimeArray -%} -foreach (var item_ in {{ parameter.VariableName }}) { urlBuilder_.Append(System.Uri.EscapeDataString("{{ parameter.Name }}")).Append('=').Append(System.Uri.EscapeDataString(item_.ToString("{{ ParameterDateTimeFormat }}", System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } +foreach (var item_ in {{ parameter.VariableName }}) +{ + urlBuilder_.Append(System.Uri.EscapeDataString("{{ parameter.Name }}")).Append('=').Append(System.Uri.EscapeDataString(item_.ToString("{{ ParameterDateTimeFormat }}", System.Globalization.CultureInfo.InvariantCulture))).Append('&'); +} {% elsif parameter.IsDateArray -%} -foreach (var item_ in {{ parameter.VariableName }}) { urlBuilder_.Append(System.Uri.EscapeDataString("{{ parameter.Name }}")).Append('=').Append(System.Uri.EscapeDataString(item_.ToString("{{ ParameterDateFormat }}", System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } +foreach (var item_ in {{ parameter.VariableName }}) +{ + urlBuilder_.Append(System.Uri.EscapeDataString("{{ parameter.Name }}")).Append('=').Append(System.Uri.EscapeDataString(item_.ToString("{{ ParameterDateFormat }}", System.Globalization.CultureInfo.InvariantCulture))).Append('&'); +} {% elsif parameter.IsDateTime -%} urlBuilder_.Append(System.Uri.EscapeDataString("{{ parameter.Name }}")).Append('=').Append(System.Uri.EscapeDataString({% if parameter.IsNullable and parameter.IsRequired %}{{ parameter.VariableName }} != null ? {% endif %}{{ parameter.VariableName }}{% if parameter.IsSystemNullable %}.Value{% endif %}.ToString("{{ ParameterDateTimeFormat }}", System.Globalization.CultureInfo.InvariantCulture){% if parameter.IsNullable and parameter.IsRequired %} : "{{ QueryNullValue }}"{% endif %})).Append('&'); {% elsif parameter.IsDate -%} urlBuilder_.Append(System.Uri.EscapeDataString("{{ parameter.Name }}")).Append('=').Append(System.Uri.EscapeDataString({% if parameter.IsNullable and parameter.IsRequired %}{{ parameter.VariableName }} != null ? {% endif %}{{ parameter.VariableName }}{% if parameter.IsSystemNullable %}.Value{% endif %}.ToString("{{ ParameterDateFormat }}", System.Globalization.CultureInfo.InvariantCulture){% if parameter.IsNullable and parameter.IsRequired %} : "{{ QueryNullValue }}"{% endif %})).Append('&'); {% elsif parameter.IsExplodedArray -%} - foreach (var item_ in {{ parameter.VariableName }}) { urlBuilder_.Append(System.Uri.EscapeDataString("{{ parameter.Name }}")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } -{% elsif parameter.IsArray -%} -bool isAfterFirst = false; foreach (var item_ in {{ parameter.VariableName }}) { - if (!isAfterFirst) - { - urlBuilder_.Append(System.Uri.EscapeDataString("{{ parameter.Name }}")).Append('='); - } - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append(','); - isAfterFirst = true; + urlBuilder_.Append(System.Uri.EscapeDataString("{{ parameter.Name }}")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } -if (isAfterFirst) +{% elsif parameter.IsArray -%} +foreach (var item_ in {{ parameter.VariableName }}) { - urlBuilder_.Length--; - urlBuilder_.Append('&'); + urlBuilder_.Append(System.Uri.EscapeDataString("{{ parameter.Name }}")).Append('='); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(item_, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } {% elsif parameter.IsDictionary -%} -foreach (var item_ in {{ parameter.VariableName }}) { urlBuilder_.Append(System.Uri.EscapeDataString(item_.Key)).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_.Value, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } +foreach (var item_ in {{ parameter.VariableName }}) +{ + urlBuilder_.Append(System.Uri.EscapeDataString(item_.Key)).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_.Value, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); +} {% elsif parameter.IsDeepObject -%} {% for property in parameter.PropertyNames -%} -if ({{parameter.Name}}.{{property.Name}} != null) +if ({{parameter.VariableName}}.{{property.Name}} != null) { - urlBuilder_.Append(System.Uri.EscapeDataString("{{parameter.Name}}[{{property.Key}}]")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString({{parameter.Name}}.{{property.Name}}, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + urlBuilder_.Append(System.Uri.EscapeDataString("{{parameter.Name}}[{{property.Key}}]")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString({{parameter.VariableName}}.{{property.Name}}, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } {% endfor -%} {% for property in parameter.CollectionPropertyNames -%} -if ({{parameter.Name}}.{{property.Name}} != null && {{parameter.Name}}.{{property.Name}}.Count > 0) +if ({{parameter.VariableName}}.{{property.Name}} != null && {{parameter.Name}}.{{property.Name}}.Count > 0) { urlBuilder_.Append(System.Uri.EscapeDataString("{{parameter.Name}}[{{property.Key}}]")).Append('='); - foreach (var p_ in {{parameter.Name}}.{{property.Name}}) + foreach (var p_ in {{parameter.VariableName}}.{{property.Name}}) { urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(p_, System.Globalization.CultureInfo.InvariantCulture))).Append(','); } @@ -47,14 +49,17 @@ if ({{parameter.Name}}.{{property.Name}} != null && {{parameter.Name}}.{{propert {% endfor -%} {% elsif parameter.Explode and parameter.IsForm and parameter.IsObject -%} {% for property in parameter.PropertyNames -%} -if ({{parameter.Name}}.{{property.Name}} != null) +if ({{parameter.VariableName}}.{{property.Name}} != null) { - urlBuilder_.Append(System.Uri.EscapeDataString("{{property.Key}}")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString({{parameter.Name}}.{{property.Name}}, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + urlBuilder_.Append(System.Uri.EscapeDataString("{{property.Key}}")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString({{parameter.VariableName}}.{{property.Name}}, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } {% endfor -%} {% elsif parameter.HasAdditionalProperties == false -%} urlBuilder_.Append(System.Uri.EscapeDataString("{{ parameter.Name }}")).Append('=').Append(System.Uri.EscapeDataString({% if parameter.IsNullable and parameter.IsRequired %}{{ parameter.VariableName }} != null ? {% endif %}ConvertToString({{ parameter.VariableName }}, System.Globalization.CultureInfo.InvariantCulture){% if parameter.IsNullable and parameter.IsRequired %} : "{{ QueryNullValue }}"{% endif %})).Append('&'); {% endif -%} {% if parameter.HasAdditionalProperties -%} -foreach (var item_ in {{parameter.Name}}.AdditionalProperties) { urlBuilder_.Append(System.Uri.EscapeDataString(item_.Key)).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_.Value, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); } +foreach (var item_ in {{parameter.VariableName}}.AdditionalProperties) +{ + urlBuilder_.Append(System.Uri.EscapeDataString(item_.Key)).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(item_.Value, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); +} {% endif -%} diff --git a/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.liquid b/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.liquid index 00ba41876..84216825b 100644 --- a/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.liquid +++ b/src/NSwag.CodeGeneration.CSharp/Templates/Client.Class.liquid @@ -22,12 +22,12 @@ {% endif -%} {% assign constructorParameters = "" -%} -{% if HasConfigurationClass -%} -{% assign constructorParameters = ConfigurationClass | append: " configuration" -%} +{% if UseBaseUrl and HasBaseUrl == false -%} +{% assign constructorParameters = "string baseUrl" %} {% endif -%} -{% if UseBaseUrl and HasBaseUrl == false and HasConfigurationClass == false -%} +{% if HasConfigurationClass -%} {% unless constructorParameters == "" -%}{% assign constructorParameters = constructorParameters | append: ", " -%}{% endunless -%} -{% assign constructorParameters = constructorParameters | append: "string baseUrl" -%} +{% assign constructorParameters = constructorParameters | append: ConfigurationClass | append: " configuration" -%} {% endif -%} {% if InjectHttpClient -%} {% unless constructorParameters == "" -%}{% assign constructorParameters = constructorParameters | append: ", " -%}{% endunless -%} @@ -306,7 +306,6 @@ {% for parameter in operation.PathParameters -%} {% if parameter.Name == pathParameterParts[0] -%} {% if parameter.IsOptional -%} -{% assign pathParameterFound = false -%} if ({{ parameter.VariableName }} != null) { {% template Client.Class.PathParameter %} @@ -318,21 +317,21 @@ {% endif -%} {% endif -%} {% endfor -%} -{% comment -%} >>> just in case {% endcomment -%} -{% unless pathParameterFound -%} - urlBuilder_.Append("{{ '{' }}{{ pathParameterParts[0] }}{{ '}' }}"); -{% endunless -%} {% comment -%} <<< just in case {% endcomment -%} {% assign nonParameterPartLengh = pathParameterParts[1] | size -%} {% if nonParameterPartLengh == 1 -%} +{% if pathParameterParts[1] == "'" -%} + urlBuilder_.Append('\''); +{% else -%} urlBuilder_.Append('{{ pathParameterParts[1] }}'); +{% endif -%} {% elsif nonParameterPartLengh > 0 -%} urlBuilder_.Append("{{ pathParameterParts[1] }}"); {% endif -%} {% else -%} -{% unless pathPart == "" -%} +{% unless pathPart == "" -%} urlBuilder_.Append("{{ pathPart }}"); -{% endunless -%} +{% endunless -%} {% endif -%} {% endfor -%} {% else -%} diff --git a/src/NSwag.CodeGeneration.Tests/VerifyHelper.cs b/src/NSwag.CodeGeneration.Tests/VerifyHelper.cs index d84fb4764..ee64bcc63 100644 --- a/src/NSwag.CodeGeneration.Tests/VerifyHelper.cs +++ b/src/NSwag.CodeGeneration.Tests/VerifyHelper.cs @@ -43,4 +43,21 @@ public static SettingsTask Verify(string output, bool scrubPragmas = true, bool .UseDirectory("Snapshots") .AutoVerify(includeBuildServer: false); } + + /// + /// Constructs a namespace-like identifier based on the caller's file name (without extension) and the caller member name. + /// + /// + /// The caller member name populated by the compiler via . + /// + /// + /// The caller file path populated by the compiler via . + /// + /// + /// A string in the format "{FileNameWithoutExtension}.{MemberName}" (e.g. MyTests.TestMethod). + /// + public static string GetNameSpace([CallerMemberName] string sourceMethod = "", [CallerFilePath] string sourceFile = "") + { + return $"{Path.GetFileNameWithoutExtension(sourceFile)}.{sourceMethod}"; + } } \ No newline at end of file