diff --git a/modules/openapi-generator/src/main/resources/csharp/HttpSigningConfiguration.mustache b/modules/openapi-generator/src/main/resources/csharp/HttpSigningConfiguration.mustache
index 2d56fde4aecd..2ec594b9ec8e 100644
--- a/modules/openapi-generator/src/main/resources/csharp/HttpSigningConfiguration.mustache
+++ b/modules/openapi-generator/src/main/resources/csharp/HttpSigningConfiguration.mustache
@@ -25,6 +25,9 @@ namespace {{packageName}}.Client
{
HashAlgorithm = HashAlgorithmName.SHA256;
SigningAlgorithm = "PKCS1-v15";
+ string framework = RuntimeInformation.FrameworkDescription;
+ _skipUrlEncode = framework.StartsWith(".NET ") &&
+ int.TryParse(framework.Substring(5).Split('.')[0], out int fwMajor) && fwMajor >= 9;
}
///
@@ -67,6 +70,14 @@ namespace {{packageName}}.Client
///
public int SignatureValidityPeriod { get; set; }
+ // On .NET 9+, HttpUtility.ParseQueryString already URL-encodes keys internally,
+ // so calling UrlEncode again would cause double-encoding and produce a signature
+ // that does not match the actual request sent by RestSharp 112+.
+ // On .NET 8 and earlier, keys must be explicitly URL-encoded so that special
+ // characters (e.g. '$' in OData params like $filter) are encoded the same way
+ // in the signature as they are in the outgoing HTTP request.
+ private readonly bool _skipUrlEncode;
+
private enum PrivateKeyType
{
None = 0,
@@ -133,8 +144,7 @@ namespace {{packageName}}.Client
foreach (var parameter in requestOptions.QueryParameters)
{
#if (NETCOREAPP)
- string framework = RuntimeInformation.FrameworkDescription;
- string key = framework.StartsWith(".NET 9") ? parameter.Key : {{#net90OrLater}}HttpUtility.UrlEncode({{/net90OrLater}}parameter.Key{{#net90OrLater}}){{/net90OrLater}};
+ string key = _skipUrlEncode ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
if (parameter.Value.Count > 1)
{ // array
foreach (var value in parameter.Value)
diff --git a/samples/client/petstore/csharp/httpclient/net10/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs b/samples/client/petstore/csharp/httpclient/net10/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
index 60d62fa0d9fa..faa479b5a2b4 100644
--- a/samples/client/petstore/csharp/httpclient/net10/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
+++ b/samples/client/petstore/csharp/httpclient/net10/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
@@ -33,6 +33,9 @@ public HttpSigningConfiguration()
{
HashAlgorithm = HashAlgorithmName.SHA256;
SigningAlgorithm = "PKCS1-v15";
+ string framework = RuntimeInformation.FrameworkDescription;
+ _skipUrlEncode = framework.StartsWith(".NET ") &&
+ int.TryParse(framework.Substring(5).Split('.')[0], out int fwMajor) && fwMajor >= 9;
}
///
@@ -75,6 +78,14 @@ public HttpSigningConfiguration()
///
public int SignatureValidityPeriod { get; set; }
+ // On .NET 9+, HttpUtility.ParseQueryString already URL-encodes keys internally,
+ // so calling UrlEncode again would cause double-encoding and produce a signature
+ // that does not match the actual request sent by RestSharp 112+.
+ // On .NET 8 and earlier, keys must be explicitly URL-encoded so that special
+ // characters (e.g. '$' in OData params like $filter) are encoded the same way
+ // in the signature as they are in the outgoing HTTP request.
+ private readonly bool _skipUrlEncode;
+
private enum PrivateKeyType
{
None = 0,
@@ -141,8 +152,7 @@ public Dictionary GetHttpSignedHeader(string basePath,string met
foreach (var parameter in requestOptions.QueryParameters)
{
#if (NETCOREAPP)
- string framework = RuntimeInformation.FrameworkDescription;
- string key = framework.StartsWith(".NET 9") ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
+ string key = _skipUrlEncode ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
if (parameter.Value.Count > 1)
{ // array
foreach (var value in parameter.Value)
diff --git a/samples/client/petstore/csharp/httpclient/net9/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs b/samples/client/petstore/csharp/httpclient/net9/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
index 60d62fa0d9fa..faa479b5a2b4 100644
--- a/samples/client/petstore/csharp/httpclient/net9/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
+++ b/samples/client/petstore/csharp/httpclient/net9/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
@@ -33,6 +33,9 @@ public HttpSigningConfiguration()
{
HashAlgorithm = HashAlgorithmName.SHA256;
SigningAlgorithm = "PKCS1-v15";
+ string framework = RuntimeInformation.FrameworkDescription;
+ _skipUrlEncode = framework.StartsWith(".NET ") &&
+ int.TryParse(framework.Substring(5).Split('.')[0], out int fwMajor) && fwMajor >= 9;
}
///
@@ -75,6 +78,14 @@ public HttpSigningConfiguration()
///
public int SignatureValidityPeriod { get; set; }
+ // On .NET 9+, HttpUtility.ParseQueryString already URL-encodes keys internally,
+ // so calling UrlEncode again would cause double-encoding and produce a signature
+ // that does not match the actual request sent by RestSharp 112+.
+ // On .NET 8 and earlier, keys must be explicitly URL-encoded so that special
+ // characters (e.g. '$' in OData params like $filter) are encoded the same way
+ // in the signature as they are in the outgoing HTTP request.
+ private readonly bool _skipUrlEncode;
+
private enum PrivateKeyType
{
None = 0,
@@ -141,8 +152,7 @@ public Dictionary GetHttpSignedHeader(string basePath,string met
foreach (var parameter in requestOptions.QueryParameters)
{
#if (NETCOREAPP)
- string framework = RuntimeInformation.FrameworkDescription;
- string key = framework.StartsWith(".NET 9") ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
+ string key = _skipUrlEncode ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
if (parameter.Value.Count > 1)
{ // array
foreach (var value in parameter.Value)
diff --git a/samples/client/petstore/csharp/httpclient/standard2.0/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs b/samples/client/petstore/csharp/httpclient/standard2.0/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
index d4067aed3c3b..725ad9dee4fd 100644
--- a/samples/client/petstore/csharp/httpclient/standard2.0/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
+++ b/samples/client/petstore/csharp/httpclient/standard2.0/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
@@ -33,6 +33,9 @@ public HttpSigningConfiguration()
{
HashAlgorithm = HashAlgorithmName.SHA256;
SigningAlgorithm = "PKCS1-v15";
+ string framework = RuntimeInformation.FrameworkDescription;
+ _skipUrlEncode = framework.StartsWith(".NET ") &&
+ int.TryParse(framework.Substring(5).Split('.')[0], out int fwMajor) && fwMajor >= 9;
}
///
@@ -75,6 +78,14 @@ public HttpSigningConfiguration()
///
public int SignatureValidityPeriod { get; set; }
+ // On .NET 9+, HttpUtility.ParseQueryString already URL-encodes keys internally,
+ // so calling UrlEncode again would cause double-encoding and produce a signature
+ // that does not match the actual request sent by RestSharp 112+.
+ // On .NET 8 and earlier, keys must be explicitly URL-encoded so that special
+ // characters (e.g. '$' in OData params like $filter) are encoded the same way
+ // in the signature as they are in the outgoing HTTP request.
+ private readonly bool _skipUrlEncode;
+
private enum PrivateKeyType
{
None = 0,
@@ -141,8 +152,7 @@ public Dictionary GetHttpSignedHeader(string basePath,string met
foreach (var parameter in requestOptions.QueryParameters)
{
#if (NETCOREAPP)
- string framework = RuntimeInformation.FrameworkDescription;
- string key = framework.StartsWith(".NET 9") ? parameter.Key : parameter.Key;
+ string key = _skipUrlEncode ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
if (parameter.Value.Count > 1)
{ // array
foreach (var value in parameter.Value)
diff --git a/samples/client/petstore/csharp/restsharp/net10/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs b/samples/client/petstore/csharp/restsharp/net10/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
index 60d62fa0d9fa..faa479b5a2b4 100644
--- a/samples/client/petstore/csharp/restsharp/net10/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
+++ b/samples/client/petstore/csharp/restsharp/net10/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
@@ -33,6 +33,9 @@ public HttpSigningConfiguration()
{
HashAlgorithm = HashAlgorithmName.SHA256;
SigningAlgorithm = "PKCS1-v15";
+ string framework = RuntimeInformation.FrameworkDescription;
+ _skipUrlEncode = framework.StartsWith(".NET ") &&
+ int.TryParse(framework.Substring(5).Split('.')[0], out int fwMajor) && fwMajor >= 9;
}
///
@@ -75,6 +78,14 @@ public HttpSigningConfiguration()
///
public int SignatureValidityPeriod { get; set; }
+ // On .NET 9+, HttpUtility.ParseQueryString already URL-encodes keys internally,
+ // so calling UrlEncode again would cause double-encoding and produce a signature
+ // that does not match the actual request sent by RestSharp 112+.
+ // On .NET 8 and earlier, keys must be explicitly URL-encoded so that special
+ // characters (e.g. '$' in OData params like $filter) are encoded the same way
+ // in the signature as they are in the outgoing HTTP request.
+ private readonly bool _skipUrlEncode;
+
private enum PrivateKeyType
{
None = 0,
@@ -141,8 +152,7 @@ public Dictionary GetHttpSignedHeader(string basePath,string met
foreach (var parameter in requestOptions.QueryParameters)
{
#if (NETCOREAPP)
- string framework = RuntimeInformation.FrameworkDescription;
- string key = framework.StartsWith(".NET 9") ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
+ string key = _skipUrlEncode ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
if (parameter.Value.Count > 1)
{ // array
foreach (var value in parameter.Value)
diff --git a/samples/client/petstore/csharp/restsharp/net4.7/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs b/samples/client/petstore/csharp/restsharp/net4.7/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
index d4067aed3c3b..725ad9dee4fd 100644
--- a/samples/client/petstore/csharp/restsharp/net4.7/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
+++ b/samples/client/petstore/csharp/restsharp/net4.7/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
@@ -33,6 +33,9 @@ public HttpSigningConfiguration()
{
HashAlgorithm = HashAlgorithmName.SHA256;
SigningAlgorithm = "PKCS1-v15";
+ string framework = RuntimeInformation.FrameworkDescription;
+ _skipUrlEncode = framework.StartsWith(".NET ") &&
+ int.TryParse(framework.Substring(5).Split('.')[0], out int fwMajor) && fwMajor >= 9;
}
///
@@ -75,6 +78,14 @@ public HttpSigningConfiguration()
///
public int SignatureValidityPeriod { get; set; }
+ // On .NET 9+, HttpUtility.ParseQueryString already URL-encodes keys internally,
+ // so calling UrlEncode again would cause double-encoding and produce a signature
+ // that does not match the actual request sent by RestSharp 112+.
+ // On .NET 8 and earlier, keys must be explicitly URL-encoded so that special
+ // characters (e.g. '$' in OData params like $filter) are encoded the same way
+ // in the signature as they are in the outgoing HTTP request.
+ private readonly bool _skipUrlEncode;
+
private enum PrivateKeyType
{
None = 0,
@@ -141,8 +152,7 @@ public Dictionary GetHttpSignedHeader(string basePath,string met
foreach (var parameter in requestOptions.QueryParameters)
{
#if (NETCOREAPP)
- string framework = RuntimeInformation.FrameworkDescription;
- string key = framework.StartsWith(".NET 9") ? parameter.Key : parameter.Key;
+ string key = _skipUrlEncode ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
if (parameter.Value.Count > 1)
{ // array
foreach (var value in parameter.Value)
diff --git a/samples/client/petstore/csharp/restsharp/net4.8/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs b/samples/client/petstore/csharp/restsharp/net4.8/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
index d4067aed3c3b..725ad9dee4fd 100644
--- a/samples/client/petstore/csharp/restsharp/net4.8/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
+++ b/samples/client/petstore/csharp/restsharp/net4.8/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
@@ -33,6 +33,9 @@ public HttpSigningConfiguration()
{
HashAlgorithm = HashAlgorithmName.SHA256;
SigningAlgorithm = "PKCS1-v15";
+ string framework = RuntimeInformation.FrameworkDescription;
+ _skipUrlEncode = framework.StartsWith(".NET ") &&
+ int.TryParse(framework.Substring(5).Split('.')[0], out int fwMajor) && fwMajor >= 9;
}
///
@@ -75,6 +78,14 @@ public HttpSigningConfiguration()
///
public int SignatureValidityPeriod { get; set; }
+ // On .NET 9+, HttpUtility.ParseQueryString already URL-encodes keys internally,
+ // so calling UrlEncode again would cause double-encoding and produce a signature
+ // that does not match the actual request sent by RestSharp 112+.
+ // On .NET 8 and earlier, keys must be explicitly URL-encoded so that special
+ // characters (e.g. '$' in OData params like $filter) are encoded the same way
+ // in the signature as they are in the outgoing HTTP request.
+ private readonly bool _skipUrlEncode;
+
private enum PrivateKeyType
{
None = 0,
@@ -141,8 +152,7 @@ public Dictionary GetHttpSignedHeader(string basePath,string met
foreach (var parameter in requestOptions.QueryParameters)
{
#if (NETCOREAPP)
- string framework = RuntimeInformation.FrameworkDescription;
- string key = framework.StartsWith(".NET 9") ? parameter.Key : parameter.Key;
+ string key = _skipUrlEncode ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
if (parameter.Value.Count > 1)
{ // array
foreach (var value in parameter.Value)
diff --git a/samples/client/petstore/csharp/restsharp/net8/EnumMappings/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs b/samples/client/petstore/csharp/restsharp/net8/EnumMappings/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
index 805b45bd0846..faa479b5a2b4 100644
--- a/samples/client/petstore/csharp/restsharp/net8/EnumMappings/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
+++ b/samples/client/petstore/csharp/restsharp/net8/EnumMappings/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
@@ -33,6 +33,9 @@ public HttpSigningConfiguration()
{
HashAlgorithm = HashAlgorithmName.SHA256;
SigningAlgorithm = "PKCS1-v15";
+ string framework = RuntimeInformation.FrameworkDescription;
+ _skipUrlEncode = framework.StartsWith(".NET ") &&
+ int.TryParse(framework.Substring(5).Split('.')[0], out int fwMajor) && fwMajor >= 9;
}
///
@@ -75,6 +78,14 @@ public HttpSigningConfiguration()
///
public int SignatureValidityPeriod { get; set; }
+ // On .NET 9+, HttpUtility.ParseQueryString already URL-encodes keys internally,
+ // so calling UrlEncode again would cause double-encoding and produce a signature
+ // that does not match the actual request sent by RestSharp 112+.
+ // On .NET 8 and earlier, keys must be explicitly URL-encoded so that special
+ // characters (e.g. '$' in OData params like $filter) are encoded the same way
+ // in the signature as they are in the outgoing HTTP request.
+ private readonly bool _skipUrlEncode;
+
private enum PrivateKeyType
{
None = 0,
@@ -141,8 +152,7 @@ public Dictionary GetHttpSignedHeader(string basePath,string met
foreach (var parameter in requestOptions.QueryParameters)
{
#if (NETCOREAPP)
- string framework = RuntimeInformation.FrameworkDescription;
- string key = framework.StartsWith(".NET 9") ? parameter.Key : parameter.Key;
+ string key = _skipUrlEncode ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
if (parameter.Value.Count > 1)
{ // array
foreach (var value in parameter.Value)
diff --git a/samples/client/petstore/csharp/restsharp/net8/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs b/samples/client/petstore/csharp/restsharp/net8/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
index 805b45bd0846..faa479b5a2b4 100644
--- a/samples/client/petstore/csharp/restsharp/net8/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
+++ b/samples/client/petstore/csharp/restsharp/net8/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
@@ -33,6 +33,9 @@ public HttpSigningConfiguration()
{
HashAlgorithm = HashAlgorithmName.SHA256;
SigningAlgorithm = "PKCS1-v15";
+ string framework = RuntimeInformation.FrameworkDescription;
+ _skipUrlEncode = framework.StartsWith(".NET ") &&
+ int.TryParse(framework.Substring(5).Split('.')[0], out int fwMajor) && fwMajor >= 9;
}
///
@@ -75,6 +78,14 @@ public HttpSigningConfiguration()
///
public int SignatureValidityPeriod { get; set; }
+ // On .NET 9+, HttpUtility.ParseQueryString already URL-encodes keys internally,
+ // so calling UrlEncode again would cause double-encoding and produce a signature
+ // that does not match the actual request sent by RestSharp 112+.
+ // On .NET 8 and earlier, keys must be explicitly URL-encoded so that special
+ // characters (e.g. '$' in OData params like $filter) are encoded the same way
+ // in the signature as they are in the outgoing HTTP request.
+ private readonly bool _skipUrlEncode;
+
private enum PrivateKeyType
{
None = 0,
@@ -141,8 +152,7 @@ public Dictionary GetHttpSignedHeader(string basePath,string met
foreach (var parameter in requestOptions.QueryParameters)
{
#if (NETCOREAPP)
- string framework = RuntimeInformation.FrameworkDescription;
- string key = framework.StartsWith(".NET 9") ? parameter.Key : parameter.Key;
+ string key = _skipUrlEncode ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
if (parameter.Value.Count > 1)
{ // array
foreach (var value in parameter.Value)
diff --git a/samples/client/petstore/csharp/restsharp/net9/EnumMappings/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs b/samples/client/petstore/csharp/restsharp/net9/EnumMappings/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
index 60d62fa0d9fa..faa479b5a2b4 100644
--- a/samples/client/petstore/csharp/restsharp/net9/EnumMappings/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
+++ b/samples/client/petstore/csharp/restsharp/net9/EnumMappings/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
@@ -33,6 +33,9 @@ public HttpSigningConfiguration()
{
HashAlgorithm = HashAlgorithmName.SHA256;
SigningAlgorithm = "PKCS1-v15";
+ string framework = RuntimeInformation.FrameworkDescription;
+ _skipUrlEncode = framework.StartsWith(".NET ") &&
+ int.TryParse(framework.Substring(5).Split('.')[0], out int fwMajor) && fwMajor >= 9;
}
///
@@ -75,6 +78,14 @@ public HttpSigningConfiguration()
///
public int SignatureValidityPeriod { get; set; }
+ // On .NET 9+, HttpUtility.ParseQueryString already URL-encodes keys internally,
+ // so calling UrlEncode again would cause double-encoding and produce a signature
+ // that does not match the actual request sent by RestSharp 112+.
+ // On .NET 8 and earlier, keys must be explicitly URL-encoded so that special
+ // characters (e.g. '$' in OData params like $filter) are encoded the same way
+ // in the signature as they are in the outgoing HTTP request.
+ private readonly bool _skipUrlEncode;
+
private enum PrivateKeyType
{
None = 0,
@@ -141,8 +152,7 @@ public Dictionary GetHttpSignedHeader(string basePath,string met
foreach (var parameter in requestOptions.QueryParameters)
{
#if (NETCOREAPP)
- string framework = RuntimeInformation.FrameworkDescription;
- string key = framework.StartsWith(".NET 9") ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
+ string key = _skipUrlEncode ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
if (parameter.Value.Count > 1)
{ // array
foreach (var value in parameter.Value)
diff --git a/samples/client/petstore/csharp/restsharp/standard2.0/ConditionalSerialization/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs b/samples/client/petstore/csharp/restsharp/standard2.0/ConditionalSerialization/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
index d4067aed3c3b..725ad9dee4fd 100644
--- a/samples/client/petstore/csharp/restsharp/standard2.0/ConditionalSerialization/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
+++ b/samples/client/petstore/csharp/restsharp/standard2.0/ConditionalSerialization/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
@@ -33,6 +33,9 @@ public HttpSigningConfiguration()
{
HashAlgorithm = HashAlgorithmName.SHA256;
SigningAlgorithm = "PKCS1-v15";
+ string framework = RuntimeInformation.FrameworkDescription;
+ _skipUrlEncode = framework.StartsWith(".NET ") &&
+ int.TryParse(framework.Substring(5).Split('.')[0], out int fwMajor) && fwMajor >= 9;
}
///
@@ -75,6 +78,14 @@ public HttpSigningConfiguration()
///
public int SignatureValidityPeriod { get; set; }
+ // On .NET 9+, HttpUtility.ParseQueryString already URL-encodes keys internally,
+ // so calling UrlEncode again would cause double-encoding and produce a signature
+ // that does not match the actual request sent by RestSharp 112+.
+ // On .NET 8 and earlier, keys must be explicitly URL-encoded so that special
+ // characters (e.g. '$' in OData params like $filter) are encoded the same way
+ // in the signature as they are in the outgoing HTTP request.
+ private readonly bool _skipUrlEncode;
+
private enum PrivateKeyType
{
None = 0,
@@ -141,8 +152,7 @@ public Dictionary GetHttpSignedHeader(string basePath,string met
foreach (var parameter in requestOptions.QueryParameters)
{
#if (NETCOREAPP)
- string framework = RuntimeInformation.FrameworkDescription;
- string key = framework.StartsWith(".NET 9") ? parameter.Key : parameter.Key;
+ string key = _skipUrlEncode ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
if (parameter.Value.Count > 1)
{ // array
foreach (var value in parameter.Value)
diff --git a/samples/client/petstore/csharp/restsharp/standard2.0/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs b/samples/client/petstore/csharp/restsharp/standard2.0/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
index d4067aed3c3b..725ad9dee4fd 100644
--- a/samples/client/petstore/csharp/restsharp/standard2.0/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
+++ b/samples/client/petstore/csharp/restsharp/standard2.0/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
@@ -33,6 +33,9 @@ public HttpSigningConfiguration()
{
HashAlgorithm = HashAlgorithmName.SHA256;
SigningAlgorithm = "PKCS1-v15";
+ string framework = RuntimeInformation.FrameworkDescription;
+ _skipUrlEncode = framework.StartsWith(".NET ") &&
+ int.TryParse(framework.Substring(5).Split('.')[0], out int fwMajor) && fwMajor >= 9;
}
///
@@ -75,6 +78,14 @@ public HttpSigningConfiguration()
///
public int SignatureValidityPeriod { get; set; }
+ // On .NET 9+, HttpUtility.ParseQueryString already URL-encodes keys internally,
+ // so calling UrlEncode again would cause double-encoding and produce a signature
+ // that does not match the actual request sent by RestSharp 112+.
+ // On .NET 8 and earlier, keys must be explicitly URL-encoded so that special
+ // characters (e.g. '$' in OData params like $filter) are encoded the same way
+ // in the signature as they are in the outgoing HTTP request.
+ private readonly bool _skipUrlEncode;
+
private enum PrivateKeyType
{
None = 0,
@@ -141,8 +152,7 @@ public Dictionary GetHttpSignedHeader(string basePath,string met
foreach (var parameter in requestOptions.QueryParameters)
{
#if (NETCOREAPP)
- string framework = RuntimeInformation.FrameworkDescription;
- string key = framework.StartsWith(".NET 9") ? parameter.Key : parameter.Key;
+ string key = _skipUrlEncode ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
if (parameter.Value.Count > 1)
{ // array
foreach (var value in parameter.Value)
diff --git a/samples/client/petstore/csharp/unityWebRequest/net10/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs b/samples/client/petstore/csharp/unityWebRequest/net10/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
index 60d62fa0d9fa..faa479b5a2b4 100644
--- a/samples/client/petstore/csharp/unityWebRequest/net10/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
+++ b/samples/client/petstore/csharp/unityWebRequest/net10/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
@@ -33,6 +33,9 @@ public HttpSigningConfiguration()
{
HashAlgorithm = HashAlgorithmName.SHA256;
SigningAlgorithm = "PKCS1-v15";
+ string framework = RuntimeInformation.FrameworkDescription;
+ _skipUrlEncode = framework.StartsWith(".NET ") &&
+ int.TryParse(framework.Substring(5).Split('.')[0], out int fwMajor) && fwMajor >= 9;
}
///
@@ -75,6 +78,14 @@ public HttpSigningConfiguration()
///
public int SignatureValidityPeriod { get; set; }
+ // On .NET 9+, HttpUtility.ParseQueryString already URL-encodes keys internally,
+ // so calling UrlEncode again would cause double-encoding and produce a signature
+ // that does not match the actual request sent by RestSharp 112+.
+ // On .NET 8 and earlier, keys must be explicitly URL-encoded so that special
+ // characters (e.g. '$' in OData params like $filter) are encoded the same way
+ // in the signature as they are in the outgoing HTTP request.
+ private readonly bool _skipUrlEncode;
+
private enum PrivateKeyType
{
None = 0,
@@ -141,8 +152,7 @@ public Dictionary GetHttpSignedHeader(string basePath,string met
foreach (var parameter in requestOptions.QueryParameters)
{
#if (NETCOREAPP)
- string framework = RuntimeInformation.FrameworkDescription;
- string key = framework.StartsWith(".NET 9") ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
+ string key = _skipUrlEncode ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
if (parameter.Value.Count > 1)
{ // array
foreach (var value in parameter.Value)
diff --git a/samples/client/petstore/csharp/unityWebRequest/net9/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs b/samples/client/petstore/csharp/unityWebRequest/net9/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
index 60d62fa0d9fa..faa479b5a2b4 100644
--- a/samples/client/petstore/csharp/unityWebRequest/net9/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
+++ b/samples/client/petstore/csharp/unityWebRequest/net9/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
@@ -33,6 +33,9 @@ public HttpSigningConfiguration()
{
HashAlgorithm = HashAlgorithmName.SHA256;
SigningAlgorithm = "PKCS1-v15";
+ string framework = RuntimeInformation.FrameworkDescription;
+ _skipUrlEncode = framework.StartsWith(".NET ") &&
+ int.TryParse(framework.Substring(5).Split('.')[0], out int fwMajor) && fwMajor >= 9;
}
///
@@ -75,6 +78,14 @@ public HttpSigningConfiguration()
///
public int SignatureValidityPeriod { get; set; }
+ // On .NET 9+, HttpUtility.ParseQueryString already URL-encodes keys internally,
+ // so calling UrlEncode again would cause double-encoding and produce a signature
+ // that does not match the actual request sent by RestSharp 112+.
+ // On .NET 8 and earlier, keys must be explicitly URL-encoded so that special
+ // characters (e.g. '$' in OData params like $filter) are encoded the same way
+ // in the signature as they are in the outgoing HTTP request.
+ private readonly bool _skipUrlEncode;
+
private enum PrivateKeyType
{
None = 0,
@@ -141,8 +152,7 @@ public Dictionary GetHttpSignedHeader(string basePath,string met
foreach (var parameter in requestOptions.QueryParameters)
{
#if (NETCOREAPP)
- string framework = RuntimeInformation.FrameworkDescription;
- string key = framework.StartsWith(".NET 9") ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
+ string key = _skipUrlEncode ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
if (parameter.Value.Count > 1)
{ // array
foreach (var value in parameter.Value)
diff --git a/samples/client/petstore/csharp/unityWebRequest/standard2.0/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs b/samples/client/petstore/csharp/unityWebRequest/standard2.0/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
index d4067aed3c3b..725ad9dee4fd 100644
--- a/samples/client/petstore/csharp/unityWebRequest/standard2.0/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
+++ b/samples/client/petstore/csharp/unityWebRequest/standard2.0/Petstore/src/Org.OpenAPITools/Client/HttpSigningConfiguration.cs
@@ -33,6 +33,9 @@ public HttpSigningConfiguration()
{
HashAlgorithm = HashAlgorithmName.SHA256;
SigningAlgorithm = "PKCS1-v15";
+ string framework = RuntimeInformation.FrameworkDescription;
+ _skipUrlEncode = framework.StartsWith(".NET ") &&
+ int.TryParse(framework.Substring(5).Split('.')[0], out int fwMajor) && fwMajor >= 9;
}
///
@@ -75,6 +78,14 @@ public HttpSigningConfiguration()
///
public int SignatureValidityPeriod { get; set; }
+ // On .NET 9+, HttpUtility.ParseQueryString already URL-encodes keys internally,
+ // so calling UrlEncode again would cause double-encoding and produce a signature
+ // that does not match the actual request sent by RestSharp 112+.
+ // On .NET 8 and earlier, keys must be explicitly URL-encoded so that special
+ // characters (e.g. '$' in OData params like $filter) are encoded the same way
+ // in the signature as they are in the outgoing HTTP request.
+ private readonly bool _skipUrlEncode;
+
private enum PrivateKeyType
{
None = 0,
@@ -141,8 +152,7 @@ public Dictionary GetHttpSignedHeader(string basePath,string met
foreach (var parameter in requestOptions.QueryParameters)
{
#if (NETCOREAPP)
- string framework = RuntimeInformation.FrameworkDescription;
- string key = framework.StartsWith(".NET 9") ? parameter.Key : parameter.Key;
+ string key = _skipUrlEncode ? parameter.Key : HttpUtility.UrlEncode(parameter.Key);
if (parameter.Value.Count > 1)
{ // array
foreach (var value in parameter.Value)