diff --git a/src/RestSharp/Authenticators/OAuth/OAuth1Authenticator.cs b/src/RestSharp/Authenticators/OAuth/OAuth1Authenticator.cs
index a4641ff5a..bd7f2da78 100644
--- a/src/RestSharp/Authenticators/OAuth/OAuth1Authenticator.cs
+++ b/src/RestSharp/Authenticators/OAuth/OAuth1Authenticator.cs
@@ -274,7 +274,7 @@ void AddOAuthData(IRestClient client, IRestRequest request, OAuthWorkflow workfl
// if this change causes trouble we need to introduce a flag indicating the specific OAuth implementation level,
// or implement a separate class for each OAuth version
static bool BaseQuery(Parameter x)
- => x.Type is ParameterType.GetOrPost or ParameterType.QueryString or ParameterType.QueryStringWithoutEncode;
+ => x.Type is ParameterType.GetOrPost or ParameterType.QueryString;
var query =
request.AlwaysMultipartFormData || request.Files.Count > 0
diff --git a/src/RestSharp/Enum.cs b/src/RestSharp/Enum.cs
index 7044888b7..0958e9a35 100644
--- a/src/RestSharp/Enum.cs
+++ b/src/RestSharp/Enum.cs
@@ -12,19 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-namespace RestSharp
-{
+namespace RestSharp {
///
/// Types of parameters that can be added to requests
///
- public enum ParameterType
- {
+ public enum ParameterType {
///
/// Cookie parameter
///
- Cookie,
- GetOrPost, UrlSegment, HttpHeader, RequestBody, QueryString,
- QueryStringWithoutEncode
+ Cookie, GetOrPost, UrlSegment, HttpHeader, RequestBody, QueryString, QueryStringWithoutEncode
}
///
@@ -35,8 +31,7 @@ public enum DataFormat { Json, Xml, None }
///
/// HTTP method to use when making requests
///
- public enum Method
- {
+ public enum Method {
GET, POST, PUT, DELETE, HEAD, OPTIONS,
PATCH, MERGE, COPY
}
@@ -44,8 +39,7 @@ public enum Method
///
/// Format strings for commonly-used date formats
///
- public struct DateFormat
- {
+ public struct DateFormat {
///
/// .NET format string for ISO 8601 date format
///
diff --git a/src/RestSharp/IRestRequest.cs b/src/RestSharp/IRestRequest.cs
index f03c12e9a..0bf2d1541 100644
--- a/src/RestSharp/IRestRequest.cs
+++ b/src/RestSharp/IRestRequest.cs
@@ -417,6 +417,15 @@ public interface IRestRequest
///
IRestRequest AddUrlSegment(string name, string value);
+ ///
+ /// Shortcut to AddParameter(name, value, UrlSegment) overload
+ ///
+ /// Name of the segment to add
+ /// Value of the segment to add
+ /// Specify false if the value should not be encoded
+ ///
+ IRestRequest AddUrlSegment(string name, string value, bool encode);
+
///
/// Shortcut to AddParameter(name, value, UrlSegment) overload
///
diff --git a/src/RestSharp/Parameter.cs b/src/RestSharp/Parameter.cs
index 6fe6efbf5..e6dab8e1b 100644
--- a/src/RestSharp/Parameter.cs
+++ b/src/RestSharp/Parameter.cs
@@ -20,25 +20,24 @@
using JetBrains.Annotations;
using RestSharp.Validation;
-namespace RestSharp
-{
+namespace RestSharp {
///
/// Parameter container for REST requests
///
[Obsolete("Use Add[XXX]Parameter methods of IRestRequest instead of instantiating the Parameter class.")]
- public class Parameter : IEquatable
- {
- public Parameter(string name, object value, ParameterType type)
- {
+ public class Parameter : IEquatable {
+ public Parameter(string name, object? value, ParameterType type, bool encode = true) {
if (type != ParameterType.RequestBody)
Ensure.NotEmpty(name, nameof(name));
- Name = name;
- Value = type != ParameterType.UrlSegment ? value : value?.ToString().Replace("%2F", "/").Replace("%2f", "/");
- Type = type;
+ Name = name;
+ Value = type != ParameterType.UrlSegment ? value : value?.ToString().Replace("%2F", "/").Replace("%2f", "/");
+ Type = type == ParameterType.QueryStringWithoutEncode ? ParameterType.QueryString : type;
+ Encode = type != ParameterType.QueryStringWithoutEncode && encode;
}
- public Parameter(string name, object value, string contentType, ParameterType type) : this(name, value, type) => ContentType = contentType;
+ public Parameter(string name, object value, string contentType, ParameterType type, bool encode = true) : this(name, value, type, encode)
+ => ContentType = contentType;
///
/// Name of the parameter
@@ -65,38 +64,36 @@ public Parameter(string name, object value, ParameterType type)
///
public string? ContentType { get; set; }
+ internal bool Encode { get; }
+
///
/// Return a human-readable representation of this parameter
///
/// String
public override string ToString() => $"{Name}={Value}";
- public bool Equals(Parameter other)
- {
+ public bool Equals(Parameter? other) {
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
- return Name == other.Name
- && Equals(Value, other.Value)
- && Type == other.Type
- && DataFormat == other.DataFormat
- && ContentType == other.ContentType;
+ return Name == other.Name &&
+ Equals(Value, other.Value) &&
+ Type == other.Type &&
+ DataFormat == other.DataFormat &&
+ ContentType == other.ContentType;
}
- public override bool Equals(object obj)
- => !ReferenceEquals(null, obj)
- && (ReferenceEquals(this, obj) || obj.GetType() == this.GetType() && Equals((Parameter) obj));
+ public override bool Equals(object? obj)
+ => !ReferenceEquals(null, obj) && (ReferenceEquals(this, obj) || obj.GetType() == GetType() && Equals((Parameter)obj));
// ReSharper disable NonReadonlyMemberInGetHashCode
- public override int GetHashCode()
- {
- unchecked
- {
+ public override int GetHashCode() {
+ unchecked {
var hashCode = Name != null ? Name.GetHashCode() : 0;
hashCode = (hashCode * 397) ^ (Value != null ? Value.GetHashCode() : 0);
- hashCode = (hashCode * 397) ^ (int) Type;
- hashCode = (hashCode * 397) ^ (int) DataFormat;
+ hashCode = (hashCode * 397) ^ (int)Type;
+ hashCode = (hashCode * 397) ^ (int)DataFormat;
hashCode = (hashCode * 397) ^ (ContentType != null ? ContentType.GetHashCode() : 0);
return hashCode;
}
@@ -104,10 +101,8 @@ public override int GetHashCode()
// ReSharper enable NonReadonlyMemberInGetHashCode
}
- public class XmlParameter : Parameter
- {
- public XmlParameter(string name, object value, string? xmlNamespace = null) : base(name, value, ParameterType.RequestBody)
- {
+ public class XmlParameter : Parameter {
+ public XmlParameter(string name, object value, string? xmlNamespace = null) : base(name, value, ParameterType.RequestBody) {
XmlNamespace = xmlNamespace;
DataFormat = DataFormat.Xml;
ContentType = Serialization.ContentType.Xml;
@@ -116,16 +111,13 @@ public XmlParameter(string name, object value, string? xmlNamespace = null) : ba
public string? XmlNamespace { get; }
}
- public class JsonParameter : Parameter
- {
- public JsonParameter(string name, object value) : base(name, value, ParameterType.RequestBody)
- {
+ public class JsonParameter : Parameter {
+ public JsonParameter(string name, object value) : base(name, value, ParameterType.RequestBody) {
DataFormat = DataFormat.Json;
ContentType = Serialization.ContentType.Json;
}
- public JsonParameter(string name, object value, string contentType) : base(name, value, ParameterType.RequestBody)
- {
+ public JsonParameter(string name, object value, string contentType) : base(name, value, ParameterType.RequestBody) {
DataFormat = DataFormat.Json;
ContentType = contentType ?? Serialization.ContentType.Json;
}
diff --git a/src/RestSharp/RestClient.cs b/src/RestSharp/RestClient.cs
index bfc84eb72..8b5d3de0c 100644
--- a/src/RestSharp/RestClient.cs
+++ b/src/RestSharp/RestClient.cs
@@ -238,7 +238,7 @@ public Uri BuildUri(IRestRequest request)
return new Uri(finalUri);
}
- string IRestClient.BuildUriWithoutQueryParameters(IRestRequest request)
+ string? IRestClient.BuildUriWithoutQueryParameters(IRestRequest request)
{
DoBuildUriValidations(request);
@@ -303,7 +303,7 @@ UrlSegmentParamsValues GetUrlSegmentParamsValues(IRestRequest request)
foreach (var parameter in parameters)
{
var paramPlaceHolder = $"{{{parameter.Name}}}";
- var paramValue = Encode(parameter.Value!.ToString());
+ var paramValue = parameter.Encode ? Encode(parameter.Value!.ToString()) : parameter.Value!.ToString();
if (hasResource) assembled = assembled.Replace(paramPlaceHolder, paramValue);
@@ -313,11 +313,11 @@ UrlSegmentParamsValues GetUrlSegmentParamsValues(IRestRequest request)
return new UrlSegmentParamsValues(builder.Uri, assembled);
}
- static string MergeBaseUrlAndResource(Uri baseUrl, string resource)
+ static string? MergeBaseUrlAndResource(Uri? baseUrl, string? resource)
{
var assembled = resource;
- if (!IsNullOrEmpty(assembled) && assembled.StartsWith("/")) assembled = assembled.Substring(1);
+ if (!IsNullOrEmpty(assembled) && assembled!.StartsWith("/")) assembled = assembled.Substring(1);
if (baseUrl == null || IsNullOrEmpty(baseUrl.AbsoluteUri)) return assembled;
@@ -326,7 +326,7 @@ static string MergeBaseUrlAndResource(Uri baseUrl, string resource)
return assembled != null ? new Uri(usingBaseUri, assembled).AbsoluteUri : baseUrl.AbsoluteUri;
}
- string ApplyQueryStringParamsValuesToUri(string mergedUri, IRestRequest request)
+ string? ApplyQueryStringParamsValuesToUri(string? mergedUri, IRestRequest request)
{
var parameters = GetQueryStringParameters(request).ToList();
parameters.AddRange(GetDefaultQueryStringParameters(request));
@@ -342,28 +342,22 @@ IEnumerable GetDefaultQueryStringParameters(IRestRequest request)
=> request.Method != Method.POST && request.Method != Method.PUT && request.Method != Method.PATCH
? DefaultParameters
.Where(
- p => p.Type == ParameterType.GetOrPost ||
- p.Type == ParameterType.QueryString ||
- p.Type == ParameterType.QueryStringWithoutEncode
+ p => p.Type is ParameterType.GetOrPost or ParameterType.QueryString
)
: DefaultParameters
.Where(
- p => p.Type == ParameterType.QueryString ||
- p.Type == ParameterType.QueryStringWithoutEncode
+ p => p.Type is ParameterType.QueryString
);
static IEnumerable GetQueryStringParameters(IRestRequest request)
=> request.Method != Method.POST && request.Method != Method.PUT && request.Method != Method.PATCH
? request.Parameters
.Where(
- p => p.Type == ParameterType.GetOrPost ||
- p.Type == ParameterType.QueryString ||
- p.Type == ParameterType.QueryStringWithoutEncode
+ p => p.Type is ParameterType.GetOrPost or ParameterType.QueryString
)
: request.Parameters
.Where(
- p => p.Type == ParameterType.QueryString ||
- p.Type == ParameterType.QueryStringWithoutEncode
+ p => p.Type is ParameterType.QueryString
);
Func? GetHandler(string contentType)
@@ -402,7 +396,7 @@ string EncodeParameters(IEnumerable parameters, Encoding encoding)
string EncodeParameter(Parameter parameter, Encoding encoding)
{
return
- parameter.Type == ParameterType.QueryStringWithoutEncode
+ !parameter.Encode
? $"{parameter.Name}={StringOrEmpty(parameter.Value)}"
: $"{EncodeQuery(parameter.Name!, encoding)}={EncodeQuery(StringOrEmpty(parameter.Value), encoding)}";
diff --git a/src/RestSharp/RestRequest.cs b/src/RestSharp/RestRequest.cs
index eb38c6132..f2a70b176 100644
--- a/src/RestSharp/RestRequest.cs
+++ b/src/RestSharp/RestRequest.cs
@@ -426,13 +426,21 @@ public IRestRequest AddOrUpdateHeaders(ICollection>
///
public IRestRequest AddUrlSegment(string name, string value) => AddParameter(name, value, ParameterType.UrlSegment);
+
+ ///
+ public IRestRequest AddUrlSegment(string name, string value, bool encode) {
+ var parameter = new Parameter(name, value, ParameterType.UrlSegment, encode);
+ return AddParameter(parameter);
+ }
///
public IRestRequest AddQueryParameter(string name, string value) => AddParameter(name, value, ParameterType.QueryString);
///
- public IRestRequest AddQueryParameter(string name, string value, bool encode)
- => AddParameter(name, value, encode ? ParameterType.QueryString : ParameterType.QueryStringWithoutEncode);
+ public IRestRequest AddQueryParameter(string name, string value, bool encode) {
+ var parameter = new Parameter(name, value, ParameterType.QueryString, encode);
+ return AddParameter(parameter);
+ }
///
public IRestRequest AddDecompressionMethod(DecompressionMethods decompressionMethod)
diff --git a/test/RestSharp.Tests/RestRequestTests.cs b/test/RestSharp.Tests/RestRequestTests.cs
index 915c4efef..3f3b0e299 100644
--- a/test/RestSharp.Tests/RestRequestTests.cs
+++ b/test/RestSharp.Tests/RestRequestTests.cs
@@ -22,10 +22,12 @@ public void RestRequest_Test_Already_Encoded()
Assert.AreEqual(2, request.Parameters.Count);
Assert.AreEqual("query", request.Parameters[0].Name);
Assert.AreEqual("Id%3d198", request.Parameters[0].Value);
- Assert.AreEqual(ParameterType.QueryStringWithoutEncode, request.Parameters[0].Type);
+ Assert.AreEqual(ParameterType.QueryString, request.Parameters[0].Type);
+ Assert.AreEqual(false, request.Parameters[0].Encode);
Assert.AreEqual("another", request.Parameters[1].Name);
Assert.AreEqual("notencoded", request.Parameters[1].Value);
- Assert.AreEqual(ParameterType.QueryStringWithoutEncode, request.Parameters[1].Type);
+ Assert.AreEqual(ParameterType.QueryString, request.Parameters[1].Type);
+ Assert.AreEqual(false, request.Parameters[1].Encode);
}
[Test]