From f18501c129e37e390748e68e322429f4f0ea7d8b Mon Sep 17 00:00:00 2001 From: Alexey Zimarev Date: Wed, 25 Feb 2026 15:11:14 +0100 Subject: [PATCH 1/6] Fix default parameters missing from RestResponse.Request.Parameters (#2282) Merge default parameters into RestRequest.Parameters early in ExecuteRequestAsync so they are visible via response.Request.Parameters. Remove the now-redundant separate merges in RequestContent, BuildUriExtensions, RequestHeaders, and OAuth1Authenticator. Co-Authored-By: Claude Opus 4.6 --- .../OAuth/OAuth1Authenticator.cs | 1 - src/RestSharp/BuildUriExtensions.cs | 7 ++----- src/RestSharp/Request/RequestContent.cs | 2 +- src/RestSharp/RestClient.Async.cs | 9 ++++++++- .../HttpHeadersTests.cs | 19 +++++++++++++++++++ 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/RestSharp/Authenticators/OAuth/OAuth1Authenticator.cs b/src/RestSharp/Authenticators/OAuth/OAuth1Authenticator.cs index 56906120f..ce4dba54e 100644 --- a/src/RestSharp/Authenticators/OAuth/OAuth1Authenticator.cs +++ b/src/RestSharp/Authenticators/OAuth/OAuth1Authenticator.cs @@ -258,7 +258,6 @@ internal static void AddOAuthData( ? x => BaseQuery(x) && x.Name != null && x.Name.StartsWith("oauth_") : (Func)BaseQuery; - parameters.AddRange(client.DefaultParameters.Where(query).ToWebParameters()); parameters.AddRange(request.Parameters.Where(query).ToWebParameters()); workflow.RequestUrl = url; diff --git a/src/RestSharp/BuildUriExtensions.cs b/src/RestSharp/BuildUriExtensions.cs index 8fb95563e..04dce88cb 100644 --- a/src/RestSharp/BuildUriExtensions.cs +++ b/src/RestSharp/BuildUriExtensions.cs @@ -53,8 +53,7 @@ public Uri BuildUriWithoutQueryParameters(RestRequest request) { var (uri, resource) = client.Options.BaseUrl.GetUrlSegmentParamsValues( request.Resource, client.Options.Encode, - request.Parameters, - client.DefaultParameters + request.Parameters ); return uri.MergeBaseUrlAndResource(resource); } @@ -66,9 +65,7 @@ public Uri BuildUriWithoutQueryParameters(RestRequest request) { /// [PublicAPI] public string? GetRequestQuery(RestRequest request) { - var parametersCollections = new ParametersCollection[] { request.Parameters, client.DefaultParameters }; - - var parameters = parametersCollections.SelectMany(x => x.GetQueryParameters(request.Method)).ToList(); + var parameters = request.Parameters.GetQueryParameters(request.Method).ToList(); return parameters.Count == 0 ? null : string.Join("&", parameters.Select(EncodeParameter).ToArray()); diff --git a/src/RestSharp/Request/RequestContent.cs b/src/RestSharp/Request/RequestContent.cs index 03af0bdcf..53ca8076d 100644 --- a/src/RestSharp/Request/RequestContent.cs +++ b/src/RestSharp/Request/RequestContent.cs @@ -24,7 +24,7 @@ namespace RestSharp; class RequestContent(IRestClient client, RestRequest request) : IDisposable { readonly List _streams = []; - readonly ParametersCollection _parameters = new RequestParameters(request.Parameters.Union(client.DefaultParameters)); + readonly ParametersCollection _parameters = request.Parameters; HttpContent? Content { get; set; } diff --git a/src/RestSharp/RestClient.Async.cs b/src/RestSharp/RestClient.Async.cs index df4558795..4869a88b9 100644 --- a/src/RestSharp/RestClient.Async.cs +++ b/src/RestSharp/RestClient.Async.cs @@ -100,6 +100,14 @@ async Task ExecuteRequestAsync(RestRequest request, CancellationTo } #endif CombineInterceptors(request); + + // Merge default parameters into the request so they are visible in response.Request.Parameters + foreach (var defaultParam in DefaultParameters) { + if (!request.Parameters.Any(p => p.Name == defaultParam.Name && p.Type == defaultParam.Type)) { + request.Parameters.AddParameter(defaultParam); + } + } + await OnBeforeRequest(request, cancellationToken).ConfigureAwait(false); request.ValidateParameters(); var authenticator = request.Authenticator ?? Options.Authenticator; @@ -131,7 +139,6 @@ async Task ExecuteRequestAsync(RestRequest request, CancellationTo var headers = new RequestHeaders() .AddHeaders(request.Parameters) - .AddHeaders(DefaultParameters) .AddAcceptHeader(AcceptedContentTypes) .AddCookieHeaders(url, cookieContainer) .AddCookieHeaders(url, Options.CookieContainer); diff --git a/test/RestSharp.Tests.Integrated/HttpHeadersTests.cs b/test/RestSharp.Tests.Integrated/HttpHeadersTests.cs index 559c6435a..dc429d0d7 100644 --- a/test/RestSharp.Tests.Integrated/HttpHeadersTests.cs +++ b/test/RestSharp.Tests.Integrated/HttpHeadersTests.cs @@ -68,6 +68,25 @@ public async Task Should_sent_custom_UserAgent() { response.GetHeaderValue("Server").Should().Be("Kestrel"); } + [Fact] + public async Task Default_headers_should_appear_in_response_request_parameters() { + const string headerName = "X-Custom-Default"; + const string headerValue = "DefaultValue123"; + + _client.AddDefaultHeader(headerName, headerValue); + + var request = new RestRequest("/headers"); + var response = await _client.ExecuteAsync(request); + + response.StatusCode.Should().Be(HttpStatusCode.OK); + + var param = response.Request.Parameters + .FirstOrDefault(p => p.Name == headerName && p.Type == ParameterType.HttpHeader); + + param.Should().NotBeNull(); + param!.Value.Should().Be(headerValue); + } + static void CheckHeader(RestResponse response, Header header) { var h = FindHeader(response, header.Name); h.Should().NotBeNull(); From 7b2c485d01699f4062886663187570d418f7de66 Mon Sep 17 00:00:00 2001 From: Alexey Zimarev Date: Wed, 25 Feb 2026 15:11:51 +0100 Subject: [PATCH 2/6] Add other files --- CLAUDE.md | 2 ++ RestSharp.slnx | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 CLAUDE.md create mode 100644 RestSharp.slnx diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..615e58179 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,2 @@ +## MCP Servers Available +- mem0: Use this AI memory for storing and retrieving long-term context as well as short-term context \ No newline at end of file diff --git a/RestSharp.slnx b/RestSharp.slnx new file mode 100644 index 000000000..d06f32574 --- /dev/null +++ b/RestSharp.slnx @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From d5a574c663888534c7c99cbd80f5ae5b3180cf96 Mon Sep 17 00:00:00 2001 From: Alexey Zimarev Date: Wed, 25 Feb 2026 15:58:52 +0100 Subject: [PATCH 3/6] Fix default parameter merging bugs introduced by #2282 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Revert per-site merging to restore original design and fix three bugs: 1. Multi-value dedup — same-name defaults (AllowMultipleDefaultParametersWithSameName) were silently dropped 2. Public API breakage — BuildUriString/GetRequestQuery didn't include defaults when called outside ExecuteAsync 3. Request mutation — stale defaults persisted on reused requests when DefaultParameters changed Add MergedParameters property on RestResponse to satisfy the original #2282 requirement of making default parameters visible after execution. Co-Authored-By: Claude Opus 4.6 --- .../OAuth/OAuth1Authenticator.cs | 1 + src/RestSharp/BuildUriExtensions.cs | 7 +- src/RestSharp/Request/RequestContent.cs | 2 +- src/RestSharp/Response/RestResponseBase.cs | 6 ++ src/RestSharp/RestClient.Async.cs | 10 +-- .../DefaultParameterTests.cs | 75 ++++++++++++++++++- .../HttpHeadersTests.cs | 5 +- 7 files changed, 92 insertions(+), 14 deletions(-) diff --git a/src/RestSharp/Authenticators/OAuth/OAuth1Authenticator.cs b/src/RestSharp/Authenticators/OAuth/OAuth1Authenticator.cs index ce4dba54e..56906120f 100644 --- a/src/RestSharp/Authenticators/OAuth/OAuth1Authenticator.cs +++ b/src/RestSharp/Authenticators/OAuth/OAuth1Authenticator.cs @@ -258,6 +258,7 @@ internal static void AddOAuthData( ? x => BaseQuery(x) && x.Name != null && x.Name.StartsWith("oauth_") : (Func)BaseQuery; + parameters.AddRange(client.DefaultParameters.Where(query).ToWebParameters()); parameters.AddRange(request.Parameters.Where(query).ToWebParameters()); workflow.RequestUrl = url; diff --git a/src/RestSharp/BuildUriExtensions.cs b/src/RestSharp/BuildUriExtensions.cs index 04dce88cb..8fb95563e 100644 --- a/src/RestSharp/BuildUriExtensions.cs +++ b/src/RestSharp/BuildUriExtensions.cs @@ -53,7 +53,8 @@ public Uri BuildUriWithoutQueryParameters(RestRequest request) { var (uri, resource) = client.Options.BaseUrl.GetUrlSegmentParamsValues( request.Resource, client.Options.Encode, - request.Parameters + request.Parameters, + client.DefaultParameters ); return uri.MergeBaseUrlAndResource(resource); } @@ -65,7 +66,9 @@ public Uri BuildUriWithoutQueryParameters(RestRequest request) { /// [PublicAPI] public string? GetRequestQuery(RestRequest request) { - var parameters = request.Parameters.GetQueryParameters(request.Method).ToList(); + var parametersCollections = new ParametersCollection[] { request.Parameters, client.DefaultParameters }; + + var parameters = parametersCollections.SelectMany(x => x.GetQueryParameters(request.Method)).ToList(); return parameters.Count == 0 ? null : string.Join("&", parameters.Select(EncodeParameter).ToArray()); diff --git a/src/RestSharp/Request/RequestContent.cs b/src/RestSharp/Request/RequestContent.cs index 53ca8076d..03af0bdcf 100644 --- a/src/RestSharp/Request/RequestContent.cs +++ b/src/RestSharp/Request/RequestContent.cs @@ -24,7 +24,7 @@ namespace RestSharp; class RequestContent(IRestClient client, RestRequest request) : IDisposable { readonly List _streams = []; - readonly ParametersCollection _parameters = request.Parameters; + readonly ParametersCollection _parameters = new RequestParameters(request.Parameters.Union(client.DefaultParameters)); HttpContent? Content { get; set; } diff --git a/src/RestSharp/Response/RestResponseBase.cs b/src/RestSharp/Response/RestResponseBase.cs index 383895fb4..3e1f47208 100644 --- a/src/RestSharp/Response/RestResponseBase.cs +++ b/src/RestSharp/Response/RestResponseBase.cs @@ -132,6 +132,12 @@ protected RestResponseBase(RestRequest request) { /// public Version? Version { get; set; } + /// + /// Combined view of request parameters and client default parameters as they were at execution time. + /// Use this to inspect the full set of parameters that were applied to the request. + /// + public ParametersCollection? MergedParameters { get; set; } + /// /// Root element of the serialized response content, only works if deserializer supports it /// diff --git a/src/RestSharp/RestClient.Async.cs b/src/RestSharp/RestClient.Async.cs index 4869a88b9..a6142d07a 100644 --- a/src/RestSharp/RestClient.Async.cs +++ b/src/RestSharp/RestClient.Async.cs @@ -36,6 +36,7 @@ public async Task ExecuteAsync(RestRequest request, CancellationTo ) .ConfigureAwait(false) : GetErrorResponse(request, internalResponse.Exception, internalResponse.TimeoutToken); + response.MergedParameters = new RequestParameters(request.Parameters.Union(DefaultParameters)); await OnAfterRequest(response, cancellationToken).ConfigureAwait(false); return Options.ThrowOnAnyError ? response.ThrowIfError() : response; @@ -100,14 +101,6 @@ async Task ExecuteRequestAsync(RestRequest request, CancellationTo } #endif CombineInterceptors(request); - - // Merge default parameters into the request so they are visible in response.Request.Parameters - foreach (var defaultParam in DefaultParameters) { - if (!request.Parameters.Any(p => p.Name == defaultParam.Name && p.Type == defaultParam.Type)) { - request.Parameters.AddParameter(defaultParam); - } - } - await OnBeforeRequest(request, cancellationToken).ConfigureAwait(false); request.ValidateParameters(); var authenticator = request.Authenticator ?? Options.Authenticator; @@ -139,6 +132,7 @@ async Task ExecuteRequestAsync(RestRequest request, CancellationTo var headers = new RequestHeaders() .AddHeaders(request.Parameters) + .AddHeaders(DefaultParameters) .AddAcceptHeader(AcceptedContentTypes) .AddCookieHeaders(url, cookieContainer) .AddCookieHeaders(url, Options.CookieContainer); diff --git a/test/RestSharp.Tests.Integrated/DefaultParameterTests.cs b/test/RestSharp.Tests.Integrated/DefaultParameterTests.cs index c2038f6a3..836d544d2 100644 --- a/test/RestSharp.Tests.Integrated/DefaultParameterTests.cs +++ b/test/RestSharp.Tests.Integrated/DefaultParameterTests.cs @@ -4,7 +4,8 @@ namespace RestSharp.Tests.Integrated; public sealed class DefaultParameterTests(WireMockTestServer server) : IClassFixture { - readonly RequestBodyCapturer _capturer = server.ConfigureBodyCapturer(Method.Get, false); + readonly RequestBodyCapturer _capturer = server.ConfigureBodyCapturer(Method.Get, false); + readonly RequestBodyCapturer _capturerOnPath = server.ConfigureBodyCapturer(Method.Get); [Fact] public async Task Should_add_default_and_request_query_get_parameters() { @@ -48,4 +49,76 @@ public async Task Should_not_encode_pipe_character_when_encode_is_false() { var query = _capturer.RawUrl.Split('?')[1]; query.Should().Contain("ids=in:001|116"); } + + [Fact] + public async Task Should_include_multiple_default_query_params_with_same_name() { + using var client = new RestClient( + new RestClientOptions(server.Url!) { AllowMultipleDefaultParametersWithSameName = true } + ); + client.AddDefaultParameter("filter", "active", ParameterType.QueryString); + client.AddDefaultParameter("filter", "verified", ParameterType.QueryString); + + var request = new RestRequest("capture"); + await client.GetAsync(request); + + var query = _capturerOnPath.Url!.Query; + query.Should().Contain("filter=active"); + query.Should().Contain("filter=verified"); + } + + [Fact] + public async Task Should_include_default_query_params_in_BuildUriString_without_executing() { + using var client = new RestClient(server.Url!); + client.AddDefaultParameter("foo", "bar", ParameterType.QueryString); + + var request = new RestRequest("resource"); + var uri = client.BuildUriString(request); + + uri.Should().Contain("foo=bar"); + } + + [Fact] + public async Task Should_not_permanently_mutate_request_parameters_after_execute() { + using var client = new RestClient(server.Url!); + client.AddDefaultParameter("default_key", "default_val", ParameterType.QueryString); + + var request = new RestRequest("capture"); + var paramsBefore = request.Parameters.Count; + + await client.GetAsync(request); + + // Request parameters should not have been mutated by the execution. + request.Parameters.Count.Should().Be(paramsBefore); + + // Now replace the default parameter with a different value. + client.DefaultParameters.ReplaceParameter(new QueryParameter("default_key", "updated_val")); + + await client.GetAsync(request); + + // The second execution should use the updated default value, not the stale one. + var query = _capturerOnPath.Url!.Query; + query.Should().Contain("default_key=updated_val"); + query.Should().NotContain("default_key=default_val"); + } + + [Fact] + public async Task Should_include_default_params_in_merged_parameters_on_response() { + using var client = new RestClient(server.Url!); + client.AddDefaultParameter("default_key", "default_val", ParameterType.QueryString); + + var request = new RestRequest("capture").AddQueryParameter("req_key", "req_val"); + var response = await client.ExecuteAsync(request); + + response.MergedParameters.Should().NotBeNull(); + + var defaultParam = response.MergedParameters! + .FirstOrDefault(p => p.Name == "default_key" && p.Type == ParameterType.QueryString); + defaultParam.Should().NotBeNull(); + defaultParam!.Value.Should().Be("default_val"); + + var requestParam = response.MergedParameters! + .FirstOrDefault(p => p.Name == "req_key" && p.Type == ParameterType.QueryString); + requestParam.Should().NotBeNull(); + requestParam!.Value.Should().Be("req_val"); + } } \ No newline at end of file diff --git a/test/RestSharp.Tests.Integrated/HttpHeadersTests.cs b/test/RestSharp.Tests.Integrated/HttpHeadersTests.cs index dc429d0d7..0b1c0df52 100644 --- a/test/RestSharp.Tests.Integrated/HttpHeadersTests.cs +++ b/test/RestSharp.Tests.Integrated/HttpHeadersTests.cs @@ -69,7 +69,7 @@ public async Task Should_sent_custom_UserAgent() { } [Fact] - public async Task Default_headers_should_appear_in_response_request_parameters() { + public async Task Default_headers_should_appear_in_response_merged_parameters() { const string headerName = "X-Custom-Default"; const string headerValue = "DefaultValue123"; @@ -80,7 +80,8 @@ public async Task Default_headers_should_appear_in_response_request_parameters() response.StatusCode.Should().Be(HttpStatusCode.OK); - var param = response.Request.Parameters + response.MergedParameters.Should().NotBeNull(); + var param = response.MergedParameters! .FirstOrDefault(p => p.Name == headerName && p.Type == ParameterType.HttpHeader); param.Should().NotBeNull(); From 2ebe93c29cbe7e885c0dadbb87d81d1341a035a6 Mon Sep 17 00:00:00 2001 From: Alexey Zimarev Date: Wed, 25 Feb 2026 18:01:40 +0100 Subject: [PATCH 4/6] Fix CI: run dotnet test on individual test projects The addition of RestSharp.slnx alongside RestSharp.sln causes MSB1011 ("more than one project or solution file") when running bare dotnet test. Run each test project explicitly instead. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/pull-request.yml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 92807d7e3..12eb9b98d 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -37,7 +37,13 @@ jobs: 9.0.x 10.0.x - name: Run tests - run: dotnet test -c Debug -f ${{ matrix.dotnet }} + run: | + dotnet test test/RestSharp.Tests -c Debug -f ${{ matrix.dotnet }} + dotnet test test/RestSharp.Tests.Integrated -c Debug -f ${{ matrix.dotnet }} + dotnet test test/RestSharp.Tests.Serializers.Json -c Debug -f ${{ matrix.dotnet }} + dotnet test test/RestSharp.Tests.Serializers.Xml -c Debug -f ${{ matrix.dotnet }} + dotnet test test/RestSharp.Tests.Serializers.Csv -c Debug -f ${{ matrix.dotnet }} + dotnet test test/RestSharp.Tests.DependencyInjection -c Debug -f ${{ matrix.dotnet }} - name: Upload Test Results if: always() uses: actions/upload-artifact@v6 @@ -65,7 +71,13 @@ jobs: 9.0.x 10.0.x - name: Run tests - run: dotnet test -f ${{ matrix.dotnet }} + run: | + dotnet test test/RestSharp.Tests -f ${{ matrix.dotnet }} + dotnet test test/RestSharp.Tests.Integrated -f ${{ matrix.dotnet }} + dotnet test test/RestSharp.Tests.Serializers.Json -f ${{ matrix.dotnet }} + dotnet test test/RestSharp.Tests.Serializers.Xml -f ${{ matrix.dotnet }} + dotnet test test/RestSharp.Tests.Serializers.Csv -f ${{ matrix.dotnet }} + dotnet test test/RestSharp.Tests.DependencyInjection -f ${{ matrix.dotnet }} - name: Upload Test Results if: always() uses: actions/upload-artifact@v6 From 001569893ec2a1c8e0781ab4877caa5823cfc500 Mon Sep 17 00:00:00 2001 From: Alexey Zimarev Date: Thu, 26 Feb 2026 13:01:00 +0100 Subject: [PATCH 5/6] Make MergedParameters non-null with internal setter - Initialize to empty RequestParameters() so consumers never need null checks - Restrict setter to internal to prevent external mutation of response state Co-Authored-By: Claude Opus 4.6 --- src/RestSharp/Response/RestResponseBase.cs | 2 +- test/RestSharp.Tests.Integrated/DefaultParameterTests.cs | 6 ++---- test/RestSharp.Tests.Integrated/HttpHeadersTests.cs | 3 +-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/RestSharp/Response/RestResponseBase.cs b/src/RestSharp/Response/RestResponseBase.cs index 3e1f47208..b54ed4e17 100644 --- a/src/RestSharp/Response/RestResponseBase.cs +++ b/src/RestSharp/Response/RestResponseBase.cs @@ -136,7 +136,7 @@ protected RestResponseBase(RestRequest request) { /// Combined view of request parameters and client default parameters as they were at execution time. /// Use this to inspect the full set of parameters that were applied to the request. /// - public ParametersCollection? MergedParameters { get; set; } + public ParametersCollection MergedParameters { get; internal set; } = new RequestParameters(); /// /// Root element of the serialized response content, only works if deserializer supports it diff --git a/test/RestSharp.Tests.Integrated/DefaultParameterTests.cs b/test/RestSharp.Tests.Integrated/DefaultParameterTests.cs index 836d544d2..da058b238 100644 --- a/test/RestSharp.Tests.Integrated/DefaultParameterTests.cs +++ b/test/RestSharp.Tests.Integrated/DefaultParameterTests.cs @@ -109,14 +109,12 @@ public async Task Should_include_default_params_in_merged_parameters_on_response var request = new RestRequest("capture").AddQueryParameter("req_key", "req_val"); var response = await client.ExecuteAsync(request); - response.MergedParameters.Should().NotBeNull(); - - var defaultParam = response.MergedParameters! + var defaultParam = response.MergedParameters .FirstOrDefault(p => p.Name == "default_key" && p.Type == ParameterType.QueryString); defaultParam.Should().NotBeNull(); defaultParam!.Value.Should().Be("default_val"); - var requestParam = response.MergedParameters! + var requestParam = response.MergedParameters .FirstOrDefault(p => p.Name == "req_key" && p.Type == ParameterType.QueryString); requestParam.Should().NotBeNull(); requestParam!.Value.Should().Be("req_val"); diff --git a/test/RestSharp.Tests.Integrated/HttpHeadersTests.cs b/test/RestSharp.Tests.Integrated/HttpHeadersTests.cs index 0b1c0df52..2a0a60084 100644 --- a/test/RestSharp.Tests.Integrated/HttpHeadersTests.cs +++ b/test/RestSharp.Tests.Integrated/HttpHeadersTests.cs @@ -80,8 +80,7 @@ public async Task Default_headers_should_appear_in_response_merged_parameters() response.StatusCode.Should().Be(HttpStatusCode.OK); - response.MergedParameters.Should().NotBeNull(); - var param = response.MergedParameters! + var param = response.MergedParameters .FirstOrDefault(p => p.Name == headerName && p.Type == ParameterType.HttpHeader); param.Should().NotBeNull(); From 351908033c7363c78cd0340ed3c1a699e7f0a38e Mon Sep 17 00:00:00 2001 From: Alexey Zimarev Date: Thu, 26 Feb 2026 13:13:15 +0100 Subject: [PATCH 6/6] Document MergedParameters property in response docs Co-Authored-By: Claude Opus 4.6 --- docs/docs/usage/response.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/docs/usage/response.md b/docs/docs/usage/response.md index dbaf302b4..43745ec39 100644 --- a/docs/docs/usage/response.md +++ b/docs/docs/usage/response.md @@ -28,6 +28,19 @@ Response object contains the following properties: | `ErrorException` | `Exception?` | Exception thrown when executing the request, if any. | | `Version` | `Version?` | HTTP protocol version of the request. | | `RootElement` | `string?` | Root element of the serialized response content, only works if deserializer supports it. | +| `MergedParameters` | `ParametersCollection` | Combined view of request parameters and client default parameters at execution time. | + +### Merged parameters + +The `MergedParameters` property provides a combined view of the request's own parameters and the client's [default parameters](request.md#request-headers) as they were at execution time. This is useful for logging or debugging the full set of parameters that were applied to a request, since `Request.Parameters` only contains the parameters added directly to the request. + +```csharp +var response = await client.ExecuteAsync(request); + +foreach (var param in response.MergedParameters) { + Console.WriteLine($"{param.Name} = {param.Value} ({param.Type})"); +} +``` In addition, `RestResponse` has one additional property: