diff --git a/Directory.Packages.props b/Directory.Packages.props
index 64df33b50..61c85f4c3 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -16,8 +16,8 @@
-
-
+
+
@@ -28,7 +28,7 @@
-
+
@@ -36,14 +36,14 @@
-
+
-
+
-
-
+
+
\ No newline at end of file
diff --git a/gen/SourceGenerator/ImmutableGenerator.cs b/gen/SourceGenerator/ImmutableGenerator.cs
index 54ea9101b..7576359bd 100644
--- a/gen/SourceGenerator/ImmutableGenerator.cs
+++ b/gen/SourceGenerator/ImmutableGenerator.cs
@@ -32,22 +32,24 @@ public void Execute(GeneratorExecutionContext context) {
static string GenerateImmutableClass(TypeDeclarationSyntax mutableClass, Compilation compilation) {
var containingNamespace = compilation.GetSemanticModel(mutableClass.SyntaxTree).GetDeclaredSymbol(mutableClass)!.ContainingNamespace;
-
- var namespaceName = containingNamespace.ToDisplayString();
-
- var className = mutableClass.Identifier.Text;
-
- var usings = mutableClass.SyntaxTree.GetCompilationUnitRoot().Usings.Select(u => u.ToString());
+ var namespaceName = containingNamespace.ToDisplayString();
+ var className = mutableClass.Identifier.Text;
+ var usings = mutableClass.SyntaxTree.GetCompilationUnitRoot().Usings.Select(u => u.ToString());
var properties = GetDefinitions(SyntaxKind.SetKeyword)
- .Select(prop => $" public {prop.Type} {prop.Identifier.Text} {{ get; }}")
+ .Select(
+ prop => {
+ var xml = prop.GetLeadingTrivia().FirstOrDefault(x => x.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia)).GetStructure();
+ return $"/// {xml} public {prop.Type} {prop.Identifier.Text} {{ get; }}";
+ }
+ )
.ToArray();
var props = GetDefinitions(SyntaxKind.SetKeyword).ToArray();
const string argName = "inner";
- var mutableProperties = props
- .Select(prop => $" {prop.Identifier.Text} = {argName}.{prop.Identifier.Text};");
+
+ var mutableProperties = props.Select(prop => $" {prop.Identifier.Text} = {argName}.{prop.Identifier.Text};");
var constructor = $$"""
public ReadOnly{{className}}({{className}} {{argName}}) {
@@ -85,7 +87,8 @@ IEnumerable GetDefinitions(SyntaxKind kind)
.OfType()
.Where(
prop =>
- prop.AccessorList!.Accessors.Any(accessor => accessor.Keyword.IsKind(kind)) && prop.AttributeLists.All(list => list.Attributes.All(attr => attr.Name.ToString() != "Exclude"))
+ prop.AccessorList!.Accessors.Any(accessor => accessor.Keyword.IsKind(kind)) &&
+ prop.AttributeLists.All(list => list.Attributes.All(attr => attr.Name.ToString() != "Exclude"))
);
}
-}
+}
\ No newline at end of file
diff --git a/src/RestSharp/Authenticators/JwtAuthenticator.cs b/src/RestSharp/Authenticators/JwtAuthenticator.cs
index 1b90bdd60..cadbd2a64 100644
--- a/src/RestSharp/Authenticators/JwtAuthenticator.cs
+++ b/src/RestSharp/Authenticators/JwtAuthenticator.cs
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-namespace RestSharp.Authenticators;
+namespace RestSharp.Authenticators;
///
/// JSON WEB TOKEN (JWT) Authenticator class.
@@ -26,7 +26,8 @@ public class JwtAuthenticator(string accessToken) : AuthenticatorBase(GetToken(a
[PublicAPI]
public void SetBearerToken(string accessToken) => Token = GetToken(accessToken);
- static string GetToken(string accessToken) => Ensure.NotEmpty(accessToken, nameof(accessToken)).StartsWith("Bearer ") ? accessToken : $"Bearer {accessToken}";
+ static string GetToken(string accessToken)
+ => Ensure.NotEmptyString(accessToken, nameof(accessToken)).StartsWith("Bearer ") ? accessToken : $"Bearer {accessToken}";
protected override ValueTask GetAuthenticationParameter(string accessToken)
=> new(new HeaderParameter(KnownHeaders.Authorization, accessToken));
diff --git a/src/RestSharp/Authenticators/OAuth/OAuthWorkflow.cs b/src/RestSharp/Authenticators/OAuth/OAuthWorkflow.cs
index 9b7a41837..894bb24f9 100644
--- a/src/RestSharp/Authenticators/OAuth/OAuthWorkflow.cs
+++ b/src/RestSharp/Authenticators/OAuth/OAuthWorkflow.cs
@@ -48,7 +48,7 @@ sealed class OAuthWorkflow {
/// Any existing, non-OAuth query parameters desired in the request
///
public OAuthParameters BuildRequestTokenSignature(string method, WebPairCollection parameters) {
- Ensure.NotEmpty(ConsumerKey, nameof(ConsumerKey));
+ Ensure.NotEmptyString(ConsumerKey, nameof(ConsumerKey));
var allParameters = new WebPairCollection();
allParameters.AddRange(parameters);
@@ -76,8 +76,8 @@ public OAuthParameters BuildRequestTokenSignature(string method, WebPairCollecti
/// The HTTP method for the intended request
/// Any existing, non-OAuth query parameters desired in the request
public OAuthParameters BuildAccessTokenSignature(string method, WebPairCollection parameters) {
- Ensure.NotEmpty(ConsumerKey, nameof(ConsumerKey));
- Ensure.NotEmpty(Token, nameof(Token));
+ Ensure.NotEmptyString(ConsumerKey, nameof(ConsumerKey));
+ Ensure.NotEmptyString(Token, nameof(Token));
var allParameters = new WebPairCollection();
allParameters.AddRange(parameters);
@@ -105,8 +105,8 @@ public OAuthParameters BuildAccessTokenSignature(string method, WebPairCollectio
/// The HTTP method for the intended request
/// Any existing, non-OAuth query parameters desired in the request
public OAuthParameters BuildClientAuthAccessTokenSignature(string method, WebPairCollection parameters) {
- Ensure.NotEmpty(ConsumerKey, nameof(ConsumerKey));
- Ensure.NotEmpty(ClientUsername, nameof(ClientUsername));
+ Ensure.NotEmptyString(ConsumerKey, nameof(ConsumerKey));
+ Ensure.NotEmptyString(ClientUsername, nameof(ClientUsername));
var allParameters = new WebPairCollection();
allParameters.AddRange(parameters);
@@ -127,7 +127,7 @@ public OAuthParameters BuildClientAuthAccessTokenSignature(string method, WebPai
}
public OAuthParameters BuildProtectedResourceSignature(string method, WebPairCollection parameters) {
- Ensure.NotEmpty(ConsumerKey, nameof(ConsumerKey));
+ Ensure.NotEmptyString(ConsumerKey, nameof(ConsumerKey));
var allParameters = new WebPairCollection();
allParameters.AddRange(parameters);
diff --git a/src/RestSharp/Ensure.cs b/src/RestSharp/Ensure.cs
index 5d985c860..dbdb56f9d 100644
--- a/src/RestSharp/Ensure.cs
+++ b/src/RestSharp/Ensure.cs
@@ -17,11 +17,10 @@ namespace RestSharp;
static class Ensure {
public static T NotNull(T? value, [InvokerParameterName] string name) => value ?? throw new ArgumentNullException(name);
- public static string NotEmpty(string? value, [InvokerParameterName] string name)
- => string.IsNullOrWhiteSpace(value) ? throw new ArgumentNullException(name) : value!;
-
public static string NotEmptyString(object? value, [InvokerParameterName] string name) {
var s = value as string ?? value?.ToString();
- return string.IsNullOrWhiteSpace(s) ? throw new ArgumentNullException(name) : s!;
+ if (s == null) throw new ArgumentNullException(name);
+
+ return string.IsNullOrWhiteSpace(s) ? throw new ArgumentException("Parameter cannot be an empty string", name) : s;
}
}
\ No newline at end of file
diff --git a/src/RestSharp/Options/RestClientOptions.cs b/src/RestSharp/Options/RestClientOptions.cs
index 5e924d09f..74fde4ef0 100644
--- a/src/RestSharp/Options/RestClientOptions.cs
+++ b/src/RestSharp/Options/RestClientOptions.cs
@@ -220,6 +220,7 @@ public int MaxTimeout {
///
/// Set to true to allow multiple default parameters with the same name. Default is false.
+ /// This setting doesn't apply to headers as multiple header values for the same key is allowed.
///
public bool AllowMultipleDefaultParametersWithSameName { get; set; }
diff --git a/src/RestSharp/Parameters/DefaultParameters.cs b/src/RestSharp/Parameters/DefaultParameters.cs
index 8ba19ccdc..a65b41846 100644
--- a/src/RestSharp/Parameters/DefaultParameters.cs
+++ b/src/RestSharp/Parameters/DefaultParameters.cs
@@ -28,12 +28,11 @@ public sealed class DefaultParameters(ReadOnlyRestClientOptions options) : Param
[MethodImpl(MethodImplOptions.Synchronized)]
public DefaultParameters AddParameter(Parameter parameter) {
if (parameter.Type == ParameterType.RequestBody)
- throw new NotSupportedException(
- "Cannot set request body using default parameters. Use Request.AddBody() instead."
- );
+ throw new NotSupportedException("Cannot set request body using default parameters. Use Request.AddBody() instead.");
if (!options.AllowMultipleDefaultParametersWithSameName &&
- !MultiParameterTypes.Contains(parameter.Type) &&
+ parameter.Type != ParameterType.HttpHeader &&
+ !MultiParameterTypes.Contains(parameter.Type) &&
this.Any(x => x.Name == parameter.Name)) {
throw new ArgumentException("A default parameters with the same name has already been added", nameof(parameter));
}
@@ -70,4 +69,4 @@ public DefaultParameters ReplaceParameter(Parameter parameter)
.AddParameter(parameter);
static readonly ParameterType[] MultiParameterTypes = [ParameterType.QueryString, ParameterType.GetOrPost];
-}
+}
\ No newline at end of file
diff --git a/src/RestSharp/Parameters/HeaderParameter.cs b/src/RestSharp/Parameters/HeaderParameter.cs
index 55830a63f..1607eaeda 100644
--- a/src/RestSharp/Parameters/HeaderParameter.cs
+++ b/src/RestSharp/Parameters/HeaderParameter.cs
@@ -21,5 +21,14 @@ public record HeaderParameter : Parameter {
///
/// Parameter name
/// Parameter value
- public HeaderParameter(string? name, string? value) : base(name, value, ParameterType.HttpHeader, false) { }
+ public HeaderParameter(string name, string value)
+ : base(
+ Ensure.NotEmptyString(name, nameof(name)),
+ Ensure.NotNull(value, nameof(value)),
+ ParameterType.HttpHeader,
+ false
+ ) { }
+
+ public new string Name => base.Name!;
+ public new string Value => (string)base.Value!;
}
\ No newline at end of file
diff --git a/src/RestSharp/Parameters/Parameter.cs b/src/RestSharp/Parameters/Parameter.cs
index 93de83479..903b33402 100644
--- a/src/RestSharp/Parameters/Parameter.cs
+++ b/src/RestSharp/Parameters/Parameter.cs
@@ -12,32 +12,66 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+using System.Diagnostics;
+
namespace RestSharp;
///
/// Parameter container for REST requests
///
-public abstract record Parameter(string? Name, object? Value, ParameterType Type, bool Encode) {
+[DebuggerDisplay($"{{{nameof(DebuggerDisplay)}()}}")]
+public abstract record Parameter {
+ ///
+ /// Parameter container for REST requests
+ ///
+ protected Parameter(string? name, object? value, ParameterType type, bool encode) {
+ Name = name;
+ Value = value;
+ Type = type;
+ Encode = encode;
+ }
+
///
/// MIME content type of the parameter
///
public ContentType ContentType { get; protected init; } = ContentType.Undefined;
+ public string? Name { get; }
+ public object? Value { get; }
+ public ParameterType Type { get; }
+ public bool Encode { get; }
///
/// Return a human-readable representation of this parameter
///
/// String
- public sealed override string ToString() => Value == null ? $"{Name}" : $"{Name}={Value}";
+ public sealed override string ToString() => Value == null ? $"{Name}" : $"{Name}={ValueString}";
+
+ protected virtual string ValueString => Value?.ToString() ?? "null";
public static Parameter CreateParameter(string? name, object? value, ParameterType type, bool encode = true)
// ReSharper disable once SwitchExpressionHandlesSomeKnownEnumValuesWithExceptionInDefault
=> type switch {
ParameterType.GetOrPost => new GetOrPostParameter(Ensure.NotEmptyString(name, nameof(name)), value?.ToString(), encode),
ParameterType.UrlSegment => new UrlSegmentParameter(Ensure.NotEmptyString(name, nameof(name)), value?.ToString()!, encode),
- ParameterType.HttpHeader => new HeaderParameter(name, value?.ToString()),
+ ParameterType.HttpHeader => new HeaderParameter(name!, value?.ToString()!),
ParameterType.QueryString => new QueryParameter(Ensure.NotEmptyString(name, nameof(name)), value?.ToString(), encode),
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
};
+
+ [PublicAPI]
+ public void Deconstruct(out string? name, out object? value, out ParameterType type, out bool encode) {
+ name = Name;
+ value = Value;
+ type = Type;
+ encode = Encode;
+ }
+
+ ///
+ /// Assists with debugging by displaying in the debugger output
+ ///
+ ///
+ [UsedImplicitly]
+ protected string DebuggerDisplay() => $"{GetType().Name.Replace("Parameter", "")} {ToString()}";
}
public record NamedParameter : Parameter {
diff --git a/src/RestSharp/Parameters/ParametersCollection.cs b/src/RestSharp/Parameters/ParametersCollection.cs
index 2d675820e..299f2d498 100644
--- a/src/RestSharp/Parameters/ParametersCollection.cs
+++ b/src/RestSharp/Parameters/ParametersCollection.cs
@@ -17,25 +17,27 @@
namespace RestSharp;
-public abstract class ParametersCollection : IReadOnlyCollection {
- protected readonly List Parameters = [];
+public abstract class ParametersCollection : IReadOnlyCollection where T : Parameter {
+ protected readonly List Parameters = [];
// public ParametersCollection(IEnumerable parameters) => _parameters.AddRange(parameters);
- static readonly Func SearchPredicate = (p, name)
+ static readonly Func SearchPredicate = (p, name)
=> p.Name != null && p.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase);
- public bool Exists(Parameter parameter) => Parameters.Any(p => SearchPredicate(p, parameter.Name) && p.Type == parameter.Type);
+ public bool Exists(T parameter) => Parameters.Any(p => SearchPredicate(p, parameter.Name) && p.Type == parameter.Type);
- public Parameter? TryFind(string parameterName) => Parameters.FirstOrDefault(x => SearchPredicate(x, parameterName));
+ public T? TryFind(string parameterName) => Parameters.FirstOrDefault(x => SearchPredicate(x, parameterName));
- public IEnumerable GetParameters(ParameterType parameterType) => Parameters.Where(x => x.Type == parameterType);
-
- public IEnumerable GetParameters() where T : class => Parameters.OfType();
+ public IEnumerable GetParameters() where TParameter : class, T => Parameters.OfType();
- public IEnumerator GetEnumerator() => Parameters.GetEnumerator();
+ public IEnumerator GetEnumerator() => Parameters.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public int Count => Parameters.Count;
+}
+
+public abstract class ParametersCollection : ParametersCollection {
+ public IEnumerable GetParameters(ParameterType parameterType) => Parameters.Where(x => x.Type == parameterType);
}
\ No newline at end of file
diff --git a/src/RestSharp/Parameters/RequestParameters.cs b/src/RestSharp/Parameters/RequestParameters.cs
index 96d5c8a98..2d673f9bd 100644
--- a/src/RestSharp/Parameters/RequestParameters.cs
+++ b/src/RestSharp/Parameters/RequestParameters.cs
@@ -42,7 +42,7 @@ public ParametersCollection AddParameters(IEnumerable parameters) {
}
///
- /// Add parameters from another parameters collection
+ /// Add parameters from another parameter collection
///
///
///
diff --git a/src/RestSharp/Parameters/UrlSegmentParameter.cs b/src/RestSharp/Parameters/UrlSegmentParameter.cs
index 82d6dc2fd..b9da7752a 100644
--- a/src/RestSharp/Parameters/UrlSegmentParameter.cs
+++ b/src/RestSharp/Parameters/UrlSegmentParameter.cs
@@ -29,7 +29,7 @@ public partial record UrlSegmentParameter : NamedParameter {
public UrlSegmentParameter(string name, string value, bool encode = true)
: base(
name,
- RegexPattern.Replace(Ensure.NotEmpty(value, nameof(value)), "/"),
+ RegexPattern.Replace(Ensure.NotEmptyString(value, nameof(value)), "/"),
ParameterType.UrlSegment,
encode
) { }
diff --git a/src/RestSharp/Request/HttpRequestMessageExtensions.cs b/src/RestSharp/Request/HttpRequestMessageExtensions.cs
index 00601d2d5..923f9364f 100644
--- a/src/RestSharp/Request/HttpRequestMessageExtensions.cs
+++ b/src/RestSharp/Request/HttpRequestMessageExtensions.cs
@@ -20,16 +20,16 @@ namespace RestSharp;
static class HttpRequestMessageExtensions {
public static void AddHeaders(this HttpRequestMessage message, RequestHeaders headers) {
- var headerParameters = headers.Parameters.Where(x => !KnownHeaders.IsContentHeader(x.Name!));
+ var headerParameters = headers.Where(x => !KnownHeaders.IsContentHeader(x.Name));
- headerParameters.ForEach(x => AddHeader(x, message.Headers));
+ headerParameters.GroupBy(x => x.Name).ForEach(x => AddHeader(x, message.Headers));
return;
- void AddHeader(Parameter parameter, HttpHeaders httpHeaders) {
- var parameterStringValue = parameter.Value!.ToString();
+ void AddHeader(IGrouping group, HttpHeaders httpHeaders) {
+ var parameterStringValues = group.Select(x => x.Value);
- httpHeaders.Remove(parameter.Name!);
- httpHeaders.TryAddWithoutValidation(parameter.Name!, parameterStringValue);
+ httpHeaders.Remove(group.Key);
+ httpHeaders.TryAddWithoutValidation(group.Key, parameterStringValues);
}
}
}
\ No newline at end of file
diff --git a/src/RestSharp/Request/RequestHeaders.cs b/src/RestSharp/Request/RequestHeaders.cs
index 9458cad47..10677d6e3 100644
--- a/src/RestSharp/Request/RequestHeaders.cs
+++ b/src/RestSharp/Request/RequestHeaders.cs
@@ -19,19 +19,17 @@
namespace RestSharp;
-class RequestHeaders {
- public RequestParameters Parameters { get; } = new();
-
+class RequestHeaders : ParametersCollection {
public RequestHeaders AddHeaders(ParametersCollection parameters) {
- Parameters.AddParameters(parameters.GetParameters());
+ Parameters.AddRange(parameters.GetParameters());
return this;
}
// Add Accept header based on registered deserializers if the caller has set none.
public RequestHeaders AddAcceptHeader(string[] acceptedContentTypes) {
- if (Parameters.TryFind(KnownHeaders.Accept) == null) {
+ if (TryFind(KnownHeaders.Accept) == null) {
var accepts = acceptedContentTypes.JoinToString(", ");
- Parameters.AddParameter(new HeaderParameter(KnownHeaders.Accept, accepts));
+ Parameters.Add(new(KnownHeaders.Accept, accepts));
}
return this;
@@ -46,13 +44,13 @@ public RequestHeaders AddCookieHeaders(Uri uri, CookieContainer? cookieContainer
if (string.IsNullOrWhiteSpace(cookies)) return this;
var newCookies = SplitHeader(cookies);
- var existing = Parameters.GetParameters().FirstOrDefault(x => x.Name == KnownHeaders.Cookie);
+ var existing = GetParameters().FirstOrDefault(x => x.Name == KnownHeaders.Cookie);
if (existing?.Value != null) {
- newCookies = newCookies.Union(SplitHeader(existing.Value.ToString()!));
+ newCookies = newCookies.Union(SplitHeader(existing.Value!));
}
- Parameters.AddParameter(new HeaderParameter(KnownHeaders.Cookie, string.Join("; ", newCookies)));
+ Parameters.Add(new(KnownHeaders.Cookie, string.Join("; ", newCookies)));
return this;
diff --git a/src/RestSharp/Request/RestRequest.cs b/src/RestSharp/Request/RestRequest.cs
index e0e696517..eaad89972 100644
--- a/src/RestSharp/Request/RestRequest.cs
+++ b/src/RestSharp/Request/RestRequest.cs
@@ -16,8 +16,8 @@
using RestSharp.Authenticators;
using RestSharp.Extensions;
using RestSharp.Interceptors;
-// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
+// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
// ReSharper disable UnusedAutoPropertyAccessor.Global
namespace RestSharp;
@@ -190,7 +190,7 @@ public RestRequest(Uri resource, Method method = Method.Get)
internal void IncreaseNumberOfAttempts() => Attempts++;
///
- /// How many attempts were made to send this Request
+ /// The number of attempts that were made to send this request
///
///
/// This number is incremented each time the RestClient sends the request.
diff --git a/src/RestSharp/Request/RestRequestExtensions.Headers.cs b/src/RestSharp/Request/RestRequestExtensions.Headers.cs
index dfd2d8b44..8091a1a50 100644
--- a/src/RestSharp/Request/RestRequestExtensions.Headers.cs
+++ b/src/RestSharp/Request/RestRequestExtensions.Headers.cs
@@ -17,6 +17,21 @@
namespace RestSharp;
public static partial class RestRequestExtensions {
+ ///
+ /// Adds a header to the request. RestSharp will try to separate request and content headers when calling the resource.
+ ///
+ /// Request instance
+ /// Header name
+ /// Header values
+ ///
+ public static RestRequest AddHeader(this RestRequest request, string name, string[] values) {
+ foreach (var value in values) {
+ AddHeader(request, name, value);
+ }
+
+ return request;
+ }
+
///
/// Adds a header to the request. RestSharp will try to separate request and content headers when calling the resource.
///
@@ -41,7 +56,7 @@ public static RestRequest AddHeader(this RestRequest request, string name, T
///
/// Adds or updates the request header. RestSharp will try to separate request and content headers when calling the resource.
- /// Existing header with the same name will be replaced.
+ /// The existing header with the same name will be replaced.
///
/// Request instance
/// Header name
@@ -54,7 +69,7 @@ public static RestRequest AddOrUpdateHeader(this RestRequest request, string nam
///
/// Adds or updates the request header. RestSharp will try to separate request and content headers when calling the resource.
- /// Existing header with the same name will be replaced.
+ /// The existing header with the same name will be replaced.
///
/// Request instance
/// Header name
diff --git a/src/RestSharp/Request/UriExtensions.cs b/src/RestSharp/Request/UriExtensions.cs
index f6e414f42..5aa9bd3cd 100644
--- a/src/RestSharp/Request/UriExtensions.cs
+++ b/src/RestSharp/Request/UriExtensions.cs
@@ -40,7 +40,7 @@ public static Uri AddQueryString(this Uri uri, string? query) {
var absoluteUri = uri.AbsoluteUri;
var separator = absoluteUri.Contains('?') ? "&" : "?";
- return new Uri($"{absoluteUri}{separator}{query}");
+ return new($"{absoluteUri}{separator}{query}");
}
public static UrlSegmentParamsValues GetUrlSegmentParamsValues(
diff --git a/src/RestSharp/Response/RestResponseBase.cs b/src/RestSharp/Response/RestResponseBase.cs
index 1ba9ec509..383895fb4 100644
--- a/src/RestSharp/Response/RestResponseBase.cs
+++ b/src/RestSharp/Response/RestResponseBase.cs
@@ -21,7 +21,7 @@ namespace RestSharp;
///
/// Base class for common properties shared by RestResponse and RestResponse[[T]]
///
-[DebuggerDisplay("{" + nameof(DebuggerDisplay) + "()}")]
+[DebuggerDisplay($"{{{nameof(DebuggerDisplay)}()}}")]
public abstract class RestResponseBase {
///
/// Default constructor
diff --git a/src/RestSharp/RestClient.cs b/src/RestSharp/RestClient.cs
index 0b3f58380..95fd432cb 100644
--- a/src/RestSharp/RestClient.cs
+++ b/src/RestSharp/RestClient.cs
@@ -74,8 +74,8 @@ public RestClient(
}
ConfigureSerializers(configureSerialization);
- Options = new ReadOnlyRestClientOptions(options);
- DefaultParameters = new DefaultParameters(Options);
+ Options = new(options);
+ DefaultParameters = new(Options);
if (useClientFactory) {
_disposeHttpClient = false;
@@ -121,8 +121,7 @@ public RestClient(
ConfigureHeaders? configureDefaultHeaders = null,
ConfigureSerialization? configureSerialization = null,
bool useClientFactory = false
- )
- : this(ConfigureOptions(new RestClientOptions(), configureRestClient), configureDefaultHeaders, configureSerialization, useClientFactory) { }
+ ) : this(ConfigureOptions(new(), configureRestClient), configureDefaultHeaders, configureSerialization, useClientFactory) { }
///
///
@@ -141,7 +140,7 @@ public RestClient(
bool useClientFactory = false
)
: this(
- ConfigureOptions(new RestClientOptions { BaseUrl = baseUrl }, configureRestClient),
+ ConfigureOptions(new() { BaseUrl = baseUrl }, configureRestClient),
configureDefaultHeaders,
configureSerialization,
useClientFactory
@@ -185,8 +184,8 @@ public RestClient(
}
var opt = options ?? new RestClientOptions();
- Options = new ReadOnlyRestClientOptions(opt);
- DefaultParameters = new DefaultParameters(Options);
+ Options = new(opt);
+ DefaultParameters = new(Options);
if (options != null) {
ConfigureHttpClient(httpClient, options);
@@ -207,7 +206,7 @@ public RestClient(
ConfigureRestClient? configureRestClient = null,
ConfigureSerialization? configureSerialization = null
)
- : this(httpClient, ConfigureOptions(new RestClientOptions(), configureRestClient), disposeHttpClient, configureSerialization) { }
+ : this(httpClient, ConfigureOptions(new(), configureRestClient), disposeHttpClient, configureSerialization) { }
///
/// Creates a new instance of RestSharp using the message handler provided. By default, HttpClient disposes the provided handler
@@ -270,7 +269,7 @@ void ConfigureSerializers(ConfigureSerialization? configureSerialization) {
var serializerConfig = new SerializerConfig();
serializerConfig.UseDefaultSerializers();
configureSerialization?.Invoke(serializerConfig);
- Serializers = new RestSerializers(serializerConfig);
+ Serializers = new(serializerConfig);
AcceptedContentTypes = Serializers.GetAcceptedContentTypes();
}
diff --git a/test/RestSharp.Tests.Integrated/HttpHeadersTests.cs b/test/RestSharp.Tests.Integrated/HttpHeadersTests.cs
index 6d5618283..559c6435a 100644
--- a/test/RestSharp.Tests.Integrated/HttpHeadersTests.cs
+++ b/test/RestSharp.Tests.Integrated/HttpHeadersTests.cs
@@ -50,8 +50,7 @@ public async Task Should_use_both_default_and_request_headers() {
_client.AddDefaultHeader(defaultHeader.Name, defaultHeader.Value);
- var request = new RestRequest("/headers")
- .AddHeader(requestHeader.Name, requestHeader.Value);
+ var request = new RestRequest("/headers").AddHeader(requestHeader.Name, requestHeader.Value);
var response = await _client.ExecuteAsync(request);
CheckHeader(response, defaultHeader);
diff --git a/test/RestSharp.Tests.Serializers.Xml/SampleClasses/twitter.cs b/test/RestSharp.Tests.Serializers.Xml/SampleClasses/twitter.cs
index 3a10375d9..1afe25fc3 100644
--- a/test/RestSharp.Tests.Serializers.Xml/SampleClasses/twitter.cs
+++ b/test/RestSharp.Tests.Serializers.Xml/SampleClasses/twitter.cs
@@ -1,14 +1,15 @@
using RestSharp.Serializers;
+
// ReSharper disable InconsistentNaming
// ReSharper disable UnusedMember.Global
// ReSharper disable ClassNeverInstantiated.Global
+#pragma warning disable CS8981 // The type name only contains lower-cased ascii characters. Such names may become reserved for the language.
#pragma warning disable CS8981
-namespace RestSharp.Tests.Serializers.Xml.SampleClasses;
+namespace RestSharp.Tests.Serializers.Xml.SampleClasses;
#pragma warning disable CS8981
public class status {
-#pragma warning restore CS8981
public bool truncated { get; set; }
public string created_at { get; set; }
@@ -113,4 +114,5 @@ public class complexStatus {
public long id { get; set; }
public string text { get; set; }
-}
\ No newline at end of file
+}
+#pragma warning restore CS8981
\ No newline at end of file
diff --git a/test/RestSharp.Tests/RequestHeaderTests.cs b/test/RestSharp.Tests/RequestHeaderTests.cs
index 8752dca10..6fa6c8215 100644
--- a/test/RestSharp.Tests/RequestHeaderTests.cs
+++ b/test/RestSharp.Tests/RequestHeaderTests.cs
@@ -21,7 +21,7 @@ public void AddHeaders_SameCaseDuplicatesExist_ThrowsException() {
[Fact]
public void AddHeaders_DifferentCaseDuplicatesExist_ThrowsException() {
var headers = _headers;
- headers.Add(new KeyValuePair(KnownHeaders.Accept, ContentType.Json));
+ headers.Add(new(KnownHeaders.Accept, ContentType.Json));
var request = new RestRequest();
@@ -63,7 +63,6 @@ public void AddOrUpdateHeader_ShouldUpdateExistingHeader_WhenHeaderExist() {
request.AddOrUpdateHeader(KnownHeaders.Accept, ContentType.Json);
// Assert
- var headers = GetHeaders(request);
GetHeader(request, KnownHeaders.Accept).Should().Be(ContentType.Json);
}
@@ -121,10 +120,8 @@ public void AddOrUpdateHeaders_ShouldUpdateHeaders_WhenAllExists() {
// Assert
var requestHeaders = GetHeaders(request);
- HeaderParameter[] expected = [
- new HeaderParameter(KnownHeaders.Accept, ContentType.Xml),
- new HeaderParameter(KnownHeaders.KeepAlive, "400")
- ];
+
+ HeaderParameter[] expected = [new(KnownHeaders.Accept, ContentType.Xml), new(KnownHeaders.KeepAlive, "400")];
requestHeaders.Should().BeEquivalentTo(expected);
}
@@ -151,13 +148,33 @@ public void AddOrUpdateHeaders_ShouldAddAndUpdateHeaders_WhenSomeExists() {
var requestHeaders = GetHeaders(request);
HeaderParameter[] expected = [
- new HeaderParameter(KnownHeaders.Accept, ContentType.Xml),
- new HeaderParameter(KnownHeaders.AcceptLanguage, "en-us,en;q=0.5"),
- new HeaderParameter(KnownHeaders.KeepAlive, "300")
+ new(KnownHeaders.Accept, ContentType.Xml),
+ new(KnownHeaders.AcceptLanguage, "en-us,en;q=0.5"),
+ new(KnownHeaders.KeepAlive, "300")
];
requestHeaders.Should().BeEquivalentTo(expected);
}
+ [Fact]
+ public void Should_not_allow_null_header_value() {
+ string value = null;
+ var request = new RestRequest();
+ // ReSharper disable once AssignNullToNotNullAttribute
+ Assert.Throws("value", () => request.AddHeader("name", value));
+ }
+
+ [Fact]
+ public void Should_not_allow_null_header_name() {
+ var request = new RestRequest();
+ Assert.Throws("name", () => request.AddHeader(null!, "value"));
+ }
+
+ [Fact]
+ public void Should_not_allow_empty_header_name() {
+ var request = new RestRequest();
+ Assert.Throws("name", () => request.AddHeader("", "value"));
+ }
+
static Parameter[] GetHeaders(RestRequest request) => request.Parameters.Where(x => x.Type == ParameterType.HttpHeader).ToArray();
static string GetHeader(RestRequest request, string name) => request.Parameters.FirstOrDefault(x => x.Name == name)?.Value?.ToString();