diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConstants.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConstants.java
index 83b8cd3386c..58a29c2d672 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConstants.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConstants.java
@@ -286,6 +286,9 @@ public class CodegenConstants {
public static final String SUPPORTS_ASYNC = "supportsAsync";
public static final String SUPPORTS_ASYNC_DESC = "Generate code that supports async operations.";
+ public static final String USE_VIRTUAL_FOR_HOOKS = "useVirtualForHooks";
+ public static final String USE_VIRTUAL_FOR_HOOKS_DESC = "Generate code that exposes public virtual hooks on ApiClient to customize low-level HTTP requests.";
+
public static final String EXCLUDE_TESTS = "excludeTests";
public static final String EXCLUDE_TESTS_DESC = "Specifies that no tests are to be generated.";
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpClientCodegen.java
index e6ceb69c824..46f51531eb4 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpClientCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpClientCodegen.java
@@ -108,6 +108,7 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
protected boolean supportsRetry = Boolean.TRUE;
protected boolean supportsAsync = Boolean.TRUE;
+ protected boolean useVirtualForHooks = Boolean.FALSE;
protected boolean netStandard = Boolean.FALSE;
protected boolean supportsFileParameters = Boolean.TRUE;
protected boolean supportsDateOnly = Boolean.FALSE;
@@ -853,6 +854,7 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
syncBooleanProperty(additionalProperties, CodegenConstants.EQUATABLE, this::setEquatable, this.equatable);
syncBooleanProperty(additionalProperties, CodegenConstants.VALIDATABLE, this::setValidatable, this.validatable);
syncBooleanProperty(additionalProperties, CodegenConstants.SUPPORTS_ASYNC, this::setSupportsAsync, this.supportsAsync);
+ syncBooleanProperty(additionalProperties, CodegenConstants.USE_VIRTUAL_FOR_HOOKS, this::setUseVirtualForHooks, this.useVirtualForHooks);
syncBooleanProperty(additionalProperties, SUPPORTS_RETRY, this::setSupportsRetry, this.supportsRetry);
syncBooleanProperty(additionalProperties, CodegenConstants.OPTIONAL_METHOD_ARGUMENT, this::setOptionalMethodArgumentFlag, optionalMethodArgumentFlag);
syncBooleanProperty(additionalProperties, CodegenConstants.NON_PUBLIC_API, this::setNonPublicApi, isNonPublicApi());
@@ -1216,6 +1218,10 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
this.supportsAsync = supportsAsync;
}
+ public void setUseVirtualForHooks(Boolean useVirtualForHooks) {
+ this.useVirtualForHooks = useVirtualForHooks;
+ }
+
public void setSupportsFileParameters(Boolean supportsFileParameters) {
this.supportsFileParameters = supportsFileParameters;
}
diff --git a/modules/openapi-generator/src/main/resources/csharp/ApiClient.mustache b/modules/openapi-generator/src/main/resources/csharp/ApiClient.mustache
index c386535dd95..a96011d7047 100644
--- a/modules/openapi-generator/src/main/resources/csharp/ApiClient.mustache
+++ b/modules/openapi-generator/src/main/resources/csharp/ApiClient.mustache
@@ -191,14 +191,14 @@ namespace {{packageName}}.Client
/// Allows for extending request processing for generated code.
///
/// The RestSharp request object
- partial void InterceptRequest(RestRequest request);
+ {{#useVirtualForHooks}}public virtual{{/useVirtualForHooks}}{{^useVirtualForHooks}}partial{{/useVirtualForHooks}} void InterceptRequest(RestRequest request){{#useVirtualForHooks}} { }{{/useVirtualForHooks}}{{^useVirtualForHooks}};{{/useVirtualForHooks}}
///
/// Allows for extending response processing for generated code.
///
/// The RestSharp request object
/// The RestSharp response object
- partial void InterceptResponse(RestRequest request, RestResponse response);
+ {{#useVirtualForHooks}}public virtual{{/useVirtualForHooks}}{{^useVirtualForHooks}}partial{{/useVirtualForHooks}} void InterceptResponse(RestRequest request, RestResponse response){{#useVirtualForHooks}} { }{{/useVirtualForHooks}}{{^useVirtualForHooks}};{{/useVirtualForHooks}}
///
/// Initializes a new instance of the , defaulting to the global configurations' base url.
diff --git a/modules/openapi-generator/src/main/resources/csharp/libraries/httpclient/ApiClient.mustache b/modules/openapi-generator/src/main/resources/csharp/libraries/httpclient/ApiClient.mustache
index 603284acbf3..d193fddd60d 100644
--- a/modules/openapi-generator/src/main/resources/csharp/libraries/httpclient/ApiClient.mustache
+++ b/modules/openapi-generator/src/main/resources/csharp/libraries/httpclient/ApiClient.mustache
@@ -419,8 +419,8 @@ namespace {{packageName}}.Client
return request;
}
- partial void InterceptRequest(HttpRequestMessage req);
- partial void InterceptResponse(HttpRequestMessage req, HttpResponseMessage response);
+ {{#useVirtualForHooks}}public virtual{{/useVirtualForHooks}}{{^useVirtualForHooks}}partial{{/useVirtualForHooks}} void InterceptRequest(HttpRequestMessage req){{#useVirtualForHooks}} { }{{/useVirtualForHooks}}{{^useVirtualForHooks}};{{/useVirtualForHooks}}
+ {{#useVirtualForHooks}}public virtual{{/useVirtualForHooks}}{{^useVirtualForHooks}}partial{{/useVirtualForHooks}} void InterceptResponse(HttpRequestMessage req, HttpResponseMessage response){{#useVirtualForHooks}} { }{{/useVirtualForHooks}}{{^useVirtualForHooks}};{{/useVirtualForHooks}}
private async Task> ToApiResponse(HttpResponseMessage response, object responseData, Uri uri)
{