diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java index e926235ba90..7546d89e968 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java @@ -233,6 +233,8 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen { clientPackageDir, "ApiException.cs")); supportingFiles.add(new SupportingFile("ApiResponse.mustache", clientPackageDir, "ApiResponse.cs")); + supportingFiles.add(new SupportingFile("ExceptionFactory.mustache", + clientPackageDir, "ExceptionFactory.cs")); supportingFiles.add(new SupportingFile("compile.mustache", "", "build.bat")); supportingFiles.add(new SupportingFile("compile-mono.sh.mustache", "", "build.sh")); diff --git a/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache b/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache index 1d34ff21eae..6ab34216b9f 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache @@ -17,15 +17,28 @@ using RestSharp; namespace {{packageName}}.Client { /// - /// API client is mainly responible for making the HTTP call to the API backend. + /// API client is mainly responsible for making the HTTP call to the API backend. /// - public class ApiClient + public 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(IRestRequest request); + + /// + /// Allows for extending response processing for generated code. + /// + /// The RestSharp request object + /// The RestSharp response object + partial void InterceptResponse(IRestRequest request, IRestResponse response); + /// /// Initializes a new instance of the class /// with default configuration and base path ({{basePath}}). @@ -165,6 +178,7 @@ namespace {{packageName}}.Client // set user agent RestClient.UserAgent = Configuration.UserAgent; + InterceptRequest(request); {{^supportsUWP}} var response = RestClient.Execute(request); {{/supportsUWP}} @@ -172,6 +186,8 @@ namespace {{packageName}}.Client // Using async method to perform sync call (uwp-only) var response = RestClient.ExecuteTaskAsync(request).Result; {{/supportsUWP}} + InterceptResponse(request, response); + return (Object) response; } {{#supportsAsync}} @@ -197,7 +213,9 @@ namespace {{packageName}}.Client var request = PrepareRequest( path, method, queryParams, postBody, headerParams, formParams, fileParams, pathParams, contentType); + InterceptRequest(request); var response = await RestClient.ExecuteTaskAsync(request); + InterceptResponse(request, response); return (Object)response; }{{/supportsAsync}} diff --git a/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache b/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache index eddb9d0de1f..48b2886f6c9 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache @@ -80,6 +80,17 @@ namespace {{packageName}}.Client /// Configuration. public static Configuration Default = new Configuration(); + /// + /// Default creation of exceptions for a given method name and response object + /// + public static readonly ExceptionFactory DefaultExceptionFactory = (methodName, response) => + { + int status = (int) response.StatusCode; + if (status >= 400) return new ApiException(status, String.Format("Error calling {0}: {1}", methodName, response.Content), response.Content); + if (status == 0) return new ApiException(status, String.Format("Error calling {0}: {1}", methodName, response.ErrorMessage), response.ErrorMessage); + return null; + }; + /// /// Gets or sets the HTTP timeout (milliseconds) of ApiClient. Default to 100000 milliseconds. /// diff --git a/modules/swagger-codegen/src/main/resources/csharp/ExceptionFactory.mustache b/modules/swagger-codegen/src/main/resources/csharp/ExceptionFactory.mustache new file mode 100644 index 00000000000..ad3cd2ac02f --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/csharp/ExceptionFactory.mustache @@ -0,0 +1,7 @@ +using System; +using RestSharp; + +namespace {{packageName}}.Client +{ + public delegate Exception ExceptionFactory(string methodName, IRestResponse response); +} diff --git a/modules/swagger-codegen/src/main/resources/csharp/api.mustache b/modules/swagger-codegen/src/main/resources/csharp/api.mustache index 1145421d22d..807155e4a45 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/api.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/api.mustache @@ -75,6 +75,8 @@ namespace {{packageName}}.Api /// public partial class {{classname}} : I{{classname}} { + private {{packageName}}.Client.ExceptionFactory _exceptionFactory = (name, response) => null; + /// /// Initializes a new instance of the class. /// @@ -83,6 +85,8 @@ namespace {{packageName}}.Api { this.Configuration = new Configuration(new ApiClient(basePath)); + ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory; + // ensure API client has configuration ready if (Configuration.ApiClient.Configuration == null) { @@ -103,6 +107,8 @@ namespace {{packageName}}.Api else this.Configuration = configuration; + ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory; + // ensure API client has configuration ready if (Configuration.ApiClient.Configuration == null) { @@ -135,6 +141,22 @@ namespace {{packageName}}.Api /// An instance of the Configuration public Configuration Configuration {get; set;} + /// + /// Provides a factory method hook for the creation of exceptions. + /// + public {{packageName}}.Client.ExceptionFactory ExceptionFactory + { + get + { + if (_exceptionFactory != null && _exceptionFactory.GetInvocationList().Length > 1) + { + throw new InvalidOperationException("Multicast delegate for ExceptionFactory is unsupported."); + } + return _exceptionFactory; + } + set { _exceptionFactory = value; } + } + /// /// Gets the default header. /// @@ -276,10 +298,11 @@ namespace {{packageName}}.Api int localVarStatusCode = (int) localVarResponse.StatusCode; - if (localVarStatusCode >= 400) - throw new ApiException (localVarStatusCode, "Error calling {{operationId}}: " + localVarResponse.Content, localVarResponse.Content); - else if (localVarStatusCode == 0) - throw new ApiException (localVarStatusCode, "Error calling {{operationId}}: " + localVarResponse.ErrorMessage, localVarResponse.ErrorMessage); + if (ExceptionFactory != null) + { + Exception exception = ExceptionFactory("{{operationId}}", localVarResponse); + if (exception != null) throw exception; + } {{#returnType}}return new ApiResponse<{{{returnType}}}>(localVarStatusCode, localVarResponse.Headers.ToDictionary(x => x.Name, x => x.Value.ToString()), @@ -410,10 +433,11 @@ namespace {{packageName}}.Api int localVarStatusCode = (int) localVarResponse.StatusCode; - if (localVarStatusCode >= 400) - throw new ApiException (localVarStatusCode, "Error calling {{operationId}}: " + localVarResponse.Content, localVarResponse.Content); - else if (localVarStatusCode == 0) - throw new ApiException (localVarStatusCode, "Error calling {{operationId}}: " + localVarResponse.ErrorMessage, localVarResponse.ErrorMessage); + if (ExceptionFactory != null) + { + Exception exception = ExceptionFactory("{{operationId}}", localVarResponse); + if (exception != null) throw exception; + } {{#returnType}}return new ApiResponse<{{{returnType}}}>(localVarStatusCode, localVarResponse.Headers.ToDictionary(x => x.Name, x => x.Value.ToString()),