diff --git a/pom.xml b/pom.xml
index 33f5f45881..6d4ff6b574 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,7 +12,7 @@
io.swagger.codegen.v3
swagger-codegen-generators
- 1.0.51
+ 1.0.52-SNAPSHOT
jar
@@ -256,28 +256,28 @@
org.mockito
mockito-core
- 5.11.0
+ 5.12.0
test
8
- 3.0.61
+ 3.0.62-SNAPSHOT
2.1.22
- 2.2.21
- 2.17.0
- 2.17.0
+ 2.2.22
+ 2.17.2
+ 2.17.2
2.11.1
3.3.0
2.16.1
- 1.7.0
+ 1.8.0
4.13.2
1.0.0
3.14.0
1.7.36
3.2.1
- 7.10.1
- 3.2.5
+ 7.10.2
+ 3.3.0
1.49
0.10.2
diff --git a/src/main/java/io/swagger/codegen/v3/generators/dotnet/AbstractCSharpCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/dotnet/AbstractCSharpCodegen.java
index 8b846d9a36..4af6b28480 100644
--- a/src/main/java/io/swagger/codegen/v3/generators/dotnet/AbstractCSharpCodegen.java
+++ b/src/main/java/io/swagger/codegen/v3/generators/dotnet/AbstractCSharpCodegen.java
@@ -11,6 +11,7 @@
import io.swagger.codegen.v3.generators.DefaultCodegenConfig;
import io.swagger.codegen.v3.generators.handlebars.csharp.CsharpHelper;
import io.swagger.codegen.v3.generators.handlebars.lambda.CamelCaseLambda;
+import io.swagger.codegen.v3.generators.handlebars.lambda.CapitaliseLambda;
import io.swagger.codegen.v3.generators.handlebars.lambda.IndentedLambda;
import io.swagger.codegen.v3.generators.handlebars.lambda.LowercaseLambda;
import io.swagger.codegen.v3.generators.handlebars.lambda.TitlecaseLambda;
@@ -350,6 +351,7 @@ private void addHandlebarsLambdas(Map objs) {
.put("titlecase", new TitlecaseLambda())
.put("camelcase", new CamelCaseLambda().generator(this))
.put("camelcase_param", new CamelCaseLambda().generator(this).escapeAsParamName(true))
+ .put("capitalise", new CapitaliseLambda())
.put("indented", new IndentedLambda())
.put("indented_8", new IndentedLambda(8, " "))
.put("indented_12", new IndentedLambda(12, " "))
diff --git a/src/main/java/io/swagger/codegen/v3/generators/dotnet/CSharpClientCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/dotnet/CSharpClientCodegen.java
index 9112e9cc3a..142ad9a280 100644
--- a/src/main/java/io/swagger/codegen/v3/generators/dotnet/CSharpClientCodegen.java
+++ b/src/main/java/io/swagger/codegen/v3/generators/dotnet/CSharpClientCodegen.java
@@ -29,6 +29,7 @@
public class CSharpClientCodegen extends AbstractCSharpCodegen {
@SuppressWarnings({"hiding"})
private static final Logger LOGGER = LoggerFactory.getLogger(CSharpClientCodegen.class);
+ private static final String NET471 = "v4.7.1";
private static final String NET45 = "v4.5";
private static final String NET40 = "v4.0";
private static final String NET35 = "v3.5";
@@ -48,10 +49,10 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
protected String modelDocPath = "docs/";
// Defines TargetFrameworkVersion in csproj files
- protected String targetFramework = NET45;
+ protected String targetFramework = NET471;
// Defines nuget identifiers for target framework
- protected String targetFrameworkNuget = "net45";
+ protected String targetFrameworkNuget = "net471";
protected boolean supportsAsync = Boolean.TRUE;
protected boolean supportsUWP = Boolean.FALSE;
protected boolean netStandard = Boolean.FALSE;
@@ -106,6 +107,7 @@ public CSharpClientCodegen() {
.put(NET35, ".NET Framework 3.5 compatible")
.put(NET40, ".NET Framework 4.0 compatible")
.put(NET45, ".NET Framework 4.5+ compatible")
+ .put(NET471, ".NET Framework 4.71+ compatible")
.put(NETSTANDARD, ".NET Standard 1.3 compatible")
.put(UWP, "Universal Windows Platform (IMPORTANT: this will be decommissioned and replaced by v5.0)")
.build();
@@ -186,6 +188,16 @@ public CSharpClientCodegen() {
@Override
public void processOpts() {
+
+ // process targetFramework first as it is used to get Template Dir
+ if (additionalProperties.containsKey(CodegenConstants.DOTNET_FRAMEWORK)) {
+ setTargetFramework((String) additionalProperties.get(CodegenConstants.DOTNET_FRAMEWORK));
+ } else {
+ // Ensure default is set.
+ setTargetFramework(NET471);
+ additionalProperties.put(CodegenConstants.DOTNET_FRAMEWORK, this.targetFramework);
+ }
+
super.processOpts();
/*
@@ -221,14 +233,6 @@ public void processOpts() {
additionalProperties.put(CodegenConstants.VALIDATABLE, validatable);
}
- if (additionalProperties.containsKey(CodegenConstants.DOTNET_FRAMEWORK)) {
- setTargetFramework((String) additionalProperties.get(CodegenConstants.DOTNET_FRAMEWORK));
- } else {
- // Ensure default is set.
- setTargetFramework(NET45);
- additionalProperties.put(CodegenConstants.DOTNET_FRAMEWORK, this.targetFramework);
- }
-
if (NET35.equals(this.targetFramework)) {
// This is correct, mono will require you build .NET 3.5 sources using 4.0 SDK
additionalProperties.put(MCS_NET_VERSION_KEY, "4");
@@ -273,10 +277,14 @@ public void processOpts() {
setTargetFrameworkNuget("net40");
setSupportsAsync(Boolean.FALSE);
- } else {
+ } else if (NET45.equals(this.targetFramework)) {
additionalProperties.put(MCS_NET_VERSION_KEY, "4.5.2-api");
setTargetFrameworkNuget("net45");
setSupportsAsync(Boolean.TRUE);
+ } else {
+ additionalProperties.put(MCS_NET_VERSION_KEY, "4.7.1-api");
+ setTargetFrameworkNuget("net471");
+ setSupportsAsync(Boolean.TRUE);
}
if (additionalProperties.containsKey(CodegenConstants.GENERATE_PROPERTY_CHANGED)) {
@@ -375,15 +383,17 @@ public void processOpts() {
clientPackageDir, "ReadOnlyDictionary.cs"));
}
- if (Boolean.FALSE.equals(this.netStandard) && Boolean.FALSE.equals(this.netCoreProjectFileFlag)) {
+ if (Boolean.FALSE.equals(this.netStandard) && Boolean.FALSE.equals(this.netCoreProjectFileFlag) && !NET471.equals(this.targetFramework)) {
supportingFiles.add(new SupportingFile("compile.mustache", "", "build.bat"));
supportingFiles.add(new SupportingFile("compile-mono.sh.mustache", "", "build.sh"));
- // copy package.config to nuget's standard location for project-level installs
- supportingFiles.add(new SupportingFile("packages.config.mustache", packageFolder + File.separator, "packages.config"));
+ if (!NET471.equals(this.targetFramework)) {
+ // copy package.config to nuget's standard location for project-level installs
+ supportingFiles.add(new SupportingFile("packages.config.mustache", packageFolder + File.separator, "packages.config"));
+ }
// .travis.yml for travis-ci.org CI
supportingFiles.add(new SupportingFile("travis.mustache", "", ".travis.yml"));
- } else if (Boolean.FALSE.equals(this.netCoreProjectFileFlag)) {
+ } else if (Boolean.FALSE.equals(this.netCoreProjectFileFlag) && !NET471.equals(this.targetFramework)) {
supportingFiles.add(new SupportingFile("project.json.mustache", packageFolder + File.separator, "project.json"));
}
@@ -420,7 +430,7 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
- if (optionalAssemblyInfoFlag && Boolean.FALSE.equals(this.netCoreProjectFileFlag)) {
+ if (optionalAssemblyInfoFlag && Boolean.FALSE.equals(this.netCoreProjectFileFlag) && !NET471.equals(this.targetFramework)) {
supportingFiles.add(new SupportingFile("AssemblyInfo.mustache", packageFolder + File.separator + "Properties", "AssemblyInfo.cs"));
}
if (optionalProjectFileFlag) {
@@ -501,6 +511,13 @@ public String getName() {
return "csharp";
}
+ public String getDefaultTemplateDir() {
+ if (NET471.equals(this.targetFramework)) {
+ return "csharp-471";
+ }
+ return "csharp";
+ }
+
@Override
public String getHelp() {
return "Generates a CSharp client library.";
diff --git a/src/main/resources/handlebars/csharp-471/ApiClient.mustache b/src/main/resources/handlebars/csharp-471/ApiClient.mustache
new file mode 100644
index 0000000000..a70bc9d656
--- /dev/null
+++ b/src/main/resources/handlebars/csharp-471/ApiClient.mustache
@@ -0,0 +1,602 @@
+{{>partial_header}}
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text.RegularExpressions;
+using System.IO;
+{{^netStandard}}
+{{^supportsUWP}}
+using System.Web;
+{{/supportsUWP}}
+{{/netStandard}}
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using Newtonsoft.Json;
+{{#netStandard}}
+using RestSharp.Portable;
+using RestSharp.Portable.HttpClient;
+{{/netStandard}}
+{{^netStandard}}
+using RestSharp;
+{{/netStandard}}
+
+namespace {{packageName}}.Client
+{
+ ///
+ /// API client is mainly responsible for making the HTTP call to the API backend.
+ ///
+ {{>visibility}} partial class ApiClient
+ {
+ private JsonSerializerSettings serializerSettings = new JsonSerializerSettings
+ {
+ ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
+ };
+
+ ///
+ /// Allows for extending request processing for generated code.
+ ///
+ /// The RestSharp request object
+ partial void InterceptRequest(RestRequest request);
+
+ ///
+ /// Allows for extending response processing for generated code.
+ ///
+ /// The RestSharp request object
+ /// The RestSharp response object
+ partial void InterceptResponse(RestRequest request, RestResponse response);
+
+ ///
+ /// Initializes a new instance of the class
+ /// with default configuration.
+ ///
+ public ApiClient()
+ {
+ Configuration = {{packageName}}.Client.Configuration.Default;
+ RestClient = new RestClient("{{{basePath}}}");
+ {{#netStandard}}
+ RestClient.IgnoreResponseStatusCode = true;
+ {{/netStandard}}
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ /// with default base path ({{{basePath}}}).
+ ///
+ /// An instance of Configuration.
+ public ApiClient(Configuration config)
+ {
+ Configuration = config ?? {{packageName}}.Client.Configuration.Default;
+
+ RestClient = new RestClient(Configuration.BasePath);
+ {{#netStandard}}
+ RestClient.IgnoreResponseStatusCode = true;
+ {{/netStandard}}
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ /// with default configuration.
+ ///
+ /// The base path.
+ public ApiClient(String basePath = "{{{basePath}}}")
+ {
+ if (String.IsNullOrEmpty(basePath))
+ throw new ArgumentException("basePath cannot be empty");
+
+ RestClient = new RestClient(basePath);
+ {{#netStandard}}
+ RestClient.IgnoreResponseStatusCode = true;
+ {{/netStandard}}
+ Configuration = Client.Configuration.Default;
+ }
+
+ ///
+ /// Gets or sets the default API client for making HTTP calls.
+ ///
+ /// The default API client.
+ [Obsolete("ApiClient.Default is deprecated, please use 'Configuration.Default.ApiClient' instead.")]
+ public static ApiClient Default;
+
+ ///
+ /// Gets or sets an instance of the IReadableConfiguration.
+ ///
+ /// An instance of the IReadableConfiguration.
+ ///
+ /// helps us to avoid modifying possibly global
+ /// configuration values from within a given client. It does not guarantee thread-safety
+ /// of the instance in any way.
+ ///
+ public IReadableConfiguration Configuration { get; set; }
+
+ ///
+ /// Gets or sets the RestClient.
+ ///
+ /// An instance of the RestClient
+ public RestClient RestClient { get; set; }
+
+ // Creates and sets up a RestRequest prior to a call.
+ private RestRequest PrepareRequest(
+ String path, {{^netStandard}}RestSharp.{{/netStandard}}Method method, List> queryParams, Object postBody,
+ Dictionary headerParams, Dictionary formParams,
+ Dictionary fileParams, Dictionary pathParams,
+ String contentType)
+ {
+ var request = new RestRequest(path, method);
+ {{#netStandard}}
+ // disable ResetSharp.Portable built-in serialization
+ request.Serializer = null;
+ {{/netStandard}}
+
+ // add path parameter, if any
+ foreach(var param in pathParams)
+ request.AddParameter(param.Key, param.Value, ParameterType.UrlSegment);
+
+ // add header parameter, if any
+ foreach(var param in headerParams)
+ request.AddHeader(param.Key, param.Value);
+
+ // add query parameter, if any
+ foreach(var param in queryParams)
+ request.AddQueryParameter(param.Key, param.Value);
+
+ // add form parameter, if any
+ foreach(var param in formParams)
+ request.AddParameter(param.Key, param.Value);
+
+ // add file parameter, if any
+ foreach(var param in fileParams)
+ {
+ {{#netStandard}}
+ request.AddFile(param.Value);
+ {{/netStandard}}
+ {{^netStandard}}
+ {{^supportsUWP}}
+ request.AddFile(param.Value.Name, param.Value.FileName, param.Value.ContentType);
+ {{/supportsUWP}}
+ {{#supportsUWP}}
+ byte[] paramWriter = null;
+ param.Value.Writer = delegate (Stream stream) { paramWriter = ToByteArray(stream); };
+ request.AddFile(param.Value.Name, paramWriter, param.Value.FileName, param.Value.ContentType);
+ {{/supportsUWP}}
+ {{/netStandard}}
+ }
+
+ if (postBody != null) // http body (model or byte[]) parameter
+ {
+ {{#netStandard}}
+ request.AddParameter(new Parameter { Value = postBody, Type = ParameterType.RequestBody, ContentType = contentType });
+ {{/netStandard}}
+ {{^netStandard}}
+ request.AddParameter(contentType, postBody, ParameterType.RequestBody);
+ {{/netStandard}}
+ }
+
+ return request;
+ }
+
+ ///
+ /// Makes the HTTP request (Sync).
+ ///
+ /// URL path.
+ /// HTTP method.
+ /// Query parameters.
+ /// HTTP body (POST request).
+ /// Header parameters.
+ /// Form parameters.
+ /// File parameters.
+ /// Path parameters.
+ /// Content Type of the request
+ /// Object
+ public Object CallApi(
+ String path, {{^netStandard}}RestSharp.{{/netStandard}}Method method, List> queryParams, Object postBody,
+ Dictionary headerParams, Dictionary formParams,
+ Dictionary fileParams, Dictionary pathParams,
+ String contentType)
+ {
+ var request = PrepareRequest(
+ path, method, queryParams, postBody, headerParams, formParams, fileParams,
+ pathParams, contentType);
+
+ var options = new RestClientOptions
+ {
+ Timeout = TimeSpan.FromMilliseconds(Configuration.Timeout), // Set the timeout
+ UserAgent = Configuration.UserAgent, // Set the user agent
+ BaseUrl = new Uri(Configuration.BasePath)
+ };
+ // Use the options to create a new RestClient
+ RestClient = new RestClient(options);
+ InterceptRequest(request);
+ {{#netStandard}}
+ var response = RestClient.Execute(request).Result;
+ {{/netStandard}}
+ {{^netStandard}}
+ {{^supportsUWP}}
+ var response = RestClient.Execute(request);
+ {{/supportsUWP}}
+ {{#supportsUWP}}
+ // Using async method to perform sync call (uwp-only)
+ var response = RestClient.ExecuteAsync(request).Result;
+ {{/supportsUWP}}
+ {{/netStandard}}
+ InterceptResponse(request, response);
+
+ return (Object) response;
+ }
+ {{#supportsAsync}}
+ ///
+ /// Makes the asynchronous HTTP request.
+ ///
+ /// URL path.
+ /// HTTP method.
+ /// Query parameters.
+ /// HTTP body (POST request).
+ /// Header parameters.
+ /// Form parameters.
+ /// File parameters.
+ /// Path parameters.
+ /// Content type.
+ /// The Task instance.
+ public async System.Threading.Tasks.Task