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 70d58617e024..b1e86a90ac35 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 static enum ENUM_PROPERTY_NAMING_TYPE {camelCase, PascalCase, snake_case,
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 c9a94a40f2cd..883b6ec91fb6 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;
@@ -854,6 +855,7 @@ public void processOpts() {
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());
@@ -1217,6 +1219,10 @@ public void setSupportsAsync(Boolean supportsAsync) {
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 c386535dd955..a96011d7047b 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 603284acbf33..d193fddd60d0 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)
{