From 2d1b899d559550d8ad9d1c8619c2e19cef205b70 Mon Sep 17 00:00:00 2001
From: Scott Offen <3513626+scottoffen@users.noreply.github.com>
Date: Wed, 26 Nov 2025 14:22:43 -0700
Subject: [PATCH 1/8] Update content extensions to use central method
---
.../FluentContentExtensions.cs | 203 +++++++++++++-----
src/version.json | 2 +-
2 files changed, 155 insertions(+), 50 deletions(-)
diff --git a/src/FluentHttpClient/FluentContentExtensions.cs b/src/FluentHttpClient/FluentContentExtensions.cs
index 1f439a3..e21ece2 100644
--- a/src/FluentHttpClient/FluentContentExtensions.cs
+++ b/src/FluentHttpClient/FluentContentExtensions.cs
@@ -17,10 +17,10 @@ public static class FluentContentExtensions
/// the underlying handler requires the content
/// length to be known in advance, or when streaming content may cause
/// protocol or middleware issues.
- ///
/// Buffering can have a significant memory impact for large payloads.
///
- ///
+ /// The instance.
+ /// The for method chaining.
public static HttpRequestBuilder WithBufferedContent(this HttpRequestBuilder builder)
{
builder.BufferRequestContent = true;
@@ -33,6 +33,9 @@ public static HttpRequestBuilder WithBufferedContent(this HttpRequestBuilder bui
///
/// Use this for adding any pre-built content that inherits from (e.g. ).
///
+ /// The instance.
+ /// The HTTP content to send with the request.
+ /// The for method chaining.
public static HttpRequestBuilder WithContent(
this HttpRequestBuilder builder,
HttpContent content)
@@ -44,6 +47,9 @@ public static HttpRequestBuilder WithContent(
///
/// Sets the request content using form URL encoded data represented by a dictionary.
///
+ /// The instance.
+ /// The dictionary containing form data as key-value pairs.
+ /// The for method chaining.
public static HttpRequestBuilder WithFormContent(
this HttpRequestBuilder builder,
Dictionary data)
@@ -63,6 +69,9 @@ public static HttpRequestBuilder WithFormContent(
/// Sets the request content using form URL encoded data represented by a sequence
/// of key/value pairs. Allows multiple values for the same key.
///
+ /// The instance.
+ /// The sequence of key-value pairs containing form data.
+ /// The for method chaining.
public static HttpRequestBuilder WithFormContent(
this HttpRequestBuilder builder,
IEnumerable> data)
@@ -83,77 +92,131 @@ public static HttpRequestBuilder WithFormContent(
///
/// Sets the request content using a with default encoding.
///
+ /// The instance.
+ /// The string content to send with the request.
+ /// The for method chaining.
public static HttpRequestBuilder WithContent(
this HttpRequestBuilder builder,
string content)
{
- builder.Content = new StringContent(content);
- return builder;
+ Guard.AgainstNull(content, nameof(content));
+ return builder.WithContent(content, null, null, null);
}
///
/// Sets the request content using a created with the specified encoding.
///
+ /// The instance.
+ /// The string content to send with the request.
+ /// The encoding to use for the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithContent(
this HttpRequestBuilder builder,
string content,
Encoding encoding)
{
- builder.Content = new StringContent(content, encoding);
- return builder;
+ Guard.AgainstNull(content, nameof(content));
+ Guard.AgainstNull(encoding, nameof(encoding));
+ return builder.WithContent(content, encoding, null, null);
}
///
/// Sets the request content using a with UTF-8 encoding and the specified media type.
///
+ /// The instance.
+ /// The string content to send with the request.
+ /// The media type string (e.g., "application/json").
+ /// The for method chaining.
public static HttpRequestBuilder WithContent(
this HttpRequestBuilder builder,
string content,
string mediaType)
{
- builder.Content = new StringContent(content, Encoding.UTF8, mediaType);
- return builder;
+ Guard.AgainstNull(content, nameof(content));
+ Guard.AgainstNull(mediaType, nameof(mediaType));
+ return builder.WithContent(content, null, mediaType, null);
}
///
/// Sets the request content using a with the specified encoding and media type.
///
+ /// The instance.
+ /// The string content to send with the request.
+ /// The encoding to use for the content.
+ /// The media type string (e.g., "application/json").
+ /// The for method chaining.
public static HttpRequestBuilder WithContent(
this HttpRequestBuilder builder,
string content,
Encoding encoding,
string mediaType)
{
- builder.Content = new StringContent(content, encoding, mediaType);
- return builder;
+ Guard.AgainstNull(content, nameof(content));
+ Guard.AgainstNull(encoding, nameof(encoding));
+ Guard.AgainstNull(mediaType, nameof(mediaType));
+ return builder.WithContent(content, encoding, mediaType, null);
}
///
/// Sets the request content using a and applies the specified .
///
+ /// The instance.
+ /// The string content to send with the request.
+ /// The media type header value to apply to the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithContent(
this HttpRequestBuilder builder,
string content,
MediaTypeHeaderValue mediaTypeHeaderValue)
{
- var sc = new StringContent(content);
- sc.Headers.ContentType = mediaTypeHeaderValue;
- builder.Content = sc;
- return builder;
+ Guard.AgainstNull(content, nameof(content));
+ Guard.AgainstNull(mediaTypeHeaderValue, nameof(mediaTypeHeaderValue));
+ return builder.WithContent(content, null, null, mediaTypeHeaderValue);
}
///
/// Sets the request content using a with the specified encoding and applies the given .
///
+ /// The instance.
+ /// The string content to send with the request.
+ /// The encoding to use for the content.
+ /// The media type header value to apply to the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithContent(
this HttpRequestBuilder builder,
string content,
Encoding encoding,
MediaTypeHeaderValue mediaTypeHeaderValue)
{
- var sc = new StringContent(content, encoding);
- sc.Headers.ContentType = mediaTypeHeaderValue;
- builder.Content = sc;
+ Guard.AgainstNull(content, nameof(content));
+ Guard.AgainstNull(encoding, nameof(encoding));
+ Guard.AgainstNull(mediaTypeHeaderValue, nameof(mediaTypeHeaderValue));
+ return builder.WithContent(content, encoding, null, mediaTypeHeaderValue);
+ }
+
+ private static HttpRequestBuilder WithContent(
+ this HttpRequestBuilder builder,
+ string content,
+ Encoding? encoding,
+ string? mediaType,
+ MediaTypeHeaderValue? mediaTypeHeaderValue
+ )
+ {
+ if (mediaType is not null)
+ {
+ builder.Content = new StringContent(content, encoding, mediaType);
+ }
+ else if (mediaTypeHeaderValue is not null)
+ {
+ var sc = new StringContent(content, encoding);
+ sc.Headers.ContentType = mediaTypeHeaderValue;
+ builder.Content = sc;
+ }
+ else
+ {
+ builder.Content = new StringContent(content, encoding);
+ }
+
return builder;
}
@@ -164,78 +227,99 @@ public static HttpRequestBuilder WithContent(
///
/// Sets the request content to the provided XML string using UTF-8 encoding and the default XML media type.
///
+ /// The instance.
+ /// The XML string content to send with the request.
+ /// The for method chaining.
public static HttpRequestBuilder WithXmlContent(
this HttpRequestBuilder builder,
string xml)
{
- builder.Content = new StringContent(xml, Encoding.UTF8, FluentXmlSerializer.DefaultContentType);
- return builder;
+ Guard.AgainstNull(xml, nameof(xml));
+ return builder.WithContent(xml, Encoding.UTF8, FluentXmlSerializer.DefaultContentType);
}
///
/// Sets the request content to the provided XML string using the specified encoding and the default XML media type.
///
+ /// The instance.
+ /// The XML string content to send with the request.
+ /// The encoding to use for the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithXmlContent(
this HttpRequestBuilder builder,
string xml,
Encoding encoding)
{
- builder.Content = new StringContent(xml, encoding, FluentXmlSerializer.DefaultContentType);
- return builder;
+ Guard.AgainstNull(xml, nameof(xml));
+ return builder.WithContent(xml, encoding, FluentXmlSerializer.DefaultContentType);
}
///
/// Sets the request content to the provided XML string using UTF-8 encoding and the specified media type.
///
+ /// The instance.
+ /// The XML string content to send with the request.
+ /// The media type string for the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithXmlContent(
this HttpRequestBuilder builder,
string xml,
string contentType)
{
- builder.Content = new StringContent(xml, Encoding.UTF8, contentType);
- return builder;
+ Guard.AgainstNull(xml, nameof(xml));
+ return builder.WithContent(xml, Encoding.UTF8, contentType);
}
///
/// Sets the request content to the provided XML string using UTF-8 encoding and applies the specified .
///
+ /// The instance.
+ /// The XML string content to send with the request.
+ /// The media type header value to apply to the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithXmlContent(
this HttpRequestBuilder builder,
string xml,
MediaTypeHeaderValue contentTypeHeaderValue)
{
- var sc = new StringContent(xml, Encoding.UTF8);
- sc.Headers.ContentType = contentTypeHeaderValue;
- builder.Content = sc;
- return builder;
+ Guard.AgainstNull(xml, nameof(xml));
+ return builder.WithContent(xml, Encoding.UTF8, contentTypeHeaderValue);
}
///
/// Sets the request content to the provided XML string using the specified encoding and media type string.
///
+ /// The instance.
+ /// The XML string content to send with the request.
+ /// The encoding to use for the content.
+ /// The media type string for the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithXmlContent(
this HttpRequestBuilder builder,
string xml,
Encoding encoding,
string contentType)
{
- builder.Content = new StringContent(xml, encoding, contentType);
- return builder;
+ Guard.AgainstNull(xml, nameof(xml));
+ return builder.WithContent(xml, encoding, contentType);
}
///
/// Sets the request content to the provided XML string using the specified encoding and applies the given .
///
+ /// The instance.
+ /// The XML string content to send with the request.
+ /// The encoding to use for the content.
+ /// The media type header value to apply to the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithXmlContent(
this HttpRequestBuilder builder,
string xml,
Encoding encoding,
MediaTypeHeaderValue contentTypeHeaderValue)
{
- var sc = new StringContent(xml, encoding);
- sc.Headers.ContentType = contentTypeHeaderValue;
- builder.Content = sc;
- return builder;
+ Guard.AgainstNull(xml, nameof(xml));
+ return builder.WithContent(xml, encoding, contentTypeHeaderValue);
}
#endregion
@@ -245,78 +329,99 @@ public static HttpRequestBuilder WithXmlContent(
///
/// Sets the request content to the provided JSON string using UTF-8 encoding and the default JSON media type.
///
+ /// The instance.
+ /// The JSON string content to send with the request.
+ /// The for method chaining.
public static HttpRequestBuilder WithJsonContent(
this HttpRequestBuilder builder,
string json)
{
- builder.Content = new StringContent(json, Encoding.UTF8, FluentJsonSerializer.DefaultContentType);
- return builder;
+ Guard.AgainstNull(json, nameof(json));
+ return builder.WithContent(json, Encoding.UTF8, FluentJsonSerializer.DefaultContentType);
}
///
/// Sets the request content to the provided JSON string using the specified encoding and the default JSON media type.
///
+ /// The instance.
+ /// The JSON string content to send with the request.
+ /// The encoding to use for the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithJsonContent(
this HttpRequestBuilder builder,
string json,
Encoding encoding)
{
- builder.Content = new StringContent(json, encoding, FluentJsonSerializer.DefaultContentType);
- return builder;
+ Guard.AgainstNull(json, nameof(json));
+ return builder.WithContent(json, encoding, FluentJsonSerializer.DefaultContentType);
}
///
/// Sets the request content to the provided JSON string using UTF-8 encoding and the specified media type.
///
+ /// The instance.
+ /// The JSON string content to send with the request.
+ /// The media type string for the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithJsonContent(
this HttpRequestBuilder builder,
string json,
string contentType)
{
- builder.Content = new StringContent(json, Encoding.UTF8, contentType);
- return builder;
+ Guard.AgainstNull(json, nameof(json));
+ return builder.WithContent(json, Encoding.UTF8, contentType);
}
///
/// Sets the request content to the provided JSON string using the specified encoding and media type.
///
+ /// The instance.
+ /// The JSON string content to send with the request.
+ /// The encoding to use for the content.
+ /// The media type string for the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithJsonContent(
this HttpRequestBuilder builder,
string json,
Encoding encoding,
string contentType)
{
- builder.Content = new StringContent(json, encoding, contentType);
- return builder;
+ Guard.AgainstNull(json, nameof(json));
+ return builder.WithContent(json, encoding, contentType);
}
///
/// Sets the request content to the provided JSON string using UTF-8 encoding and applies the specified content type header value.
///
+ /// The instance.
+ /// The JSON string content to send with the request.
+ /// The media type header value to apply to the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithJsonContent(
this HttpRequestBuilder builder,
string json,
MediaTypeHeaderValue contentTypeHeaderValue)
{
- var sc = new StringContent(json, Encoding.UTF8);
- sc.Headers.ContentType = contentTypeHeaderValue;
- builder.Content = sc;
- return builder;
+ Guard.AgainstNull(json, nameof(json));
+ return builder.WithContent(json, Encoding.UTF8, contentTypeHeaderValue);
}
///
/// Sets the request content to the provided JSON string using the specified encoding and applies the given content type header value.
///
+ /// The instance.
+ /// The JSON string content to send with the request.
+ /// The encoding to use for the content.
+ /// The media type header value to apply to the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithJsonContent(
this HttpRequestBuilder builder,
string json,
Encoding encoding,
MediaTypeHeaderValue contentTypeHeaderValue)
{
- var sc = new StringContent(json, encoding);
- sc.Headers.ContentType = contentTypeHeaderValue;
- builder.Content = sc;
- return builder;
+ Guard.AgainstNull(json, nameof(json));
+ return builder.WithContent(json, encoding, contentTypeHeaderValue);
}
#endregion
diff --git a/src/version.json b/src/version.json
index 175e865..1b84f5c 100644
--- a/src/version.json
+++ b/src/version.json
@@ -1,6 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json",
- "version": "5.0.0-rc2",
+ "version": "5.0.0",
"publicReleaseRefSpec": [
"^refs/heads/main$",
"^refs/heads/v\\d+(?:\\.\\d+)?$"
From 50877e3608c2371ff70379e762487ddb2dbf2bfd Mon Sep 17 00:00:00 2001
From: Scott Offen <3513626+scottoffen@users.noreply.github.com>
Date: Wed, 26 Nov 2025 15:22:52 -0700
Subject: [PATCH 2/8] Update class and method summary comments
---
.../FluentAuthenticationExtensions.cs | 28 ++--
.../FluentConditionalExtensions.cs | 14 +-
.../FluentCookieExtensions.cs | 14 +-
.../FluentHeaderExtensions.cs | 24 +--
.../FluentJsonContentExtensions.cs | 31 ++++
.../FluentJsonContentExtensionsAot.cs | 34 +++++
.../FluentJsonDeserialization.cs | 144 ++++++++++--------
src/FluentHttpClient/FluentJsonSerializer.cs | 3 +
.../FluentJsonTypedDeserialization.cs | 64 ++++----
.../FluentJsonTypedDeserializationAot.cs | 20 +++
.../FluentOptionsExtensions.cs | 13 +-
.../FluentQueryParametersExtensions.cs | 72 ++++-----
src/FluentHttpClient/FluentSendExtensions.cs | 140 ++++++++++-------
.../FluentVersionExtensions.cs | 42 ++---
.../FluentXmlContentExtensions.cs | 36 ++++-
.../FluentXmlDeserialization.cs | 40 +++--
src/FluentHttpClient/FluentXmlSerializer.cs | 14 ++
.../FluentXmlTypedDeserialization.cs | 56 ++++---
src/FluentHttpClient/Guard.cs | 3 +
src/FluentHttpClient/HttpClientExtensions.cs | 13 +-
.../HttpQueryParameterCollection.cs | 2 +-
src/FluentHttpClient/HttpRequestBuilder.cs | 52 +++----
.../HttpRequestBuilderExensions.cs | 4 +
23 files changed, 539 insertions(+), 324 deletions(-)
diff --git a/src/FluentHttpClient/FluentAuthenticationExtensions.cs b/src/FluentHttpClient/FluentAuthenticationExtensions.cs
index ebaf91f..cefa7d4 100644
--- a/src/FluentHttpClient/FluentAuthenticationExtensions.cs
+++ b/src/FluentHttpClient/FluentAuthenticationExtensions.cs
@@ -11,10 +11,10 @@ public static class FluentAuthenticationExtensions
///
/// Sets the for the request using the specified scheme and token.
///
- ///
- ///
- ///
- ///
+ /// The instance.
+ /// The authentication scheme (e.g., "Bearer", "Basic").
+ /// The authentication token or credentials.
+ /// The for method chaining.
public static HttpRequestBuilder WithAuthentication(this HttpRequestBuilder builder, string scheme, string token)
{
Guard.AgainstNull(scheme, nameof(scheme));
@@ -31,9 +31,9 @@ public static HttpRequestBuilder WithAuthentication(this HttpRequestBuilder buil
///
/// Sets the authentication header to Basic using the specified token value.
///
- ///
- ///
- ///
+ /// The instance.
+ /// The Base64-encoded Basic authentication token.
+ /// The for method chaining.
public static HttpRequestBuilder WithBasicAuthentication(this HttpRequestBuilder builder, string token)
{
Guard.AgainstNull(token, nameof(token));
@@ -47,10 +47,10 @@ public static HttpRequestBuilder WithBasicAuthentication(this HttpRequestBuilder
///
/// The username and password will be properly concatenated and Base64 encoded.
///
- ///
- ///
- ///
- ///
+ /// The instance.
+ /// The username for Basic authentication.
+ /// The password for Basic authentication.
+ /// The for method chaining.
public static HttpRequestBuilder WithBasicAuthentication(this HttpRequestBuilder builder, string username, string password)
{
Guard.AgainstNull(username, nameof(username));
@@ -63,9 +63,9 @@ public static HttpRequestBuilder WithBasicAuthentication(this HttpRequestBuilder
///
/// Sets the authentication header to Bearer using the specified OAuth token.
///
- ///
- ///
- ///
+ /// The instance.
+ /// The OAuth Bearer token.
+ /// The for method chaining.
public static HttpRequestBuilder WithOAuthBearerToken(this HttpRequestBuilder builder, string token)
{
Guard.AgainstNull(token, nameof(token));
diff --git a/src/FluentHttpClient/FluentConditionalExtensions.cs b/src/FluentHttpClient/FluentConditionalExtensions.cs
index 2b069ce..bf3294d 100644
--- a/src/FluentHttpClient/FluentConditionalExtensions.cs
+++ b/src/FluentHttpClient/FluentConditionalExtensions.cs
@@ -21,9 +21,10 @@ public static class FluentConditionalExtensions
/// around the configuration logic, but keeps the control flow within the fluent
/// pipeline.
///
- ///
- ///
- ///
+ /// The instance.
+ /// The boolean condition that determines whether to apply the configuration.
+ /// The action to invoke when the condition is true.
+ /// The for method chaining.
public static HttpRequestBuilder When(
this HttpRequestBuilder builder,
bool condition,
@@ -50,9 +51,10 @@ public static HttpRequestBuilder When(
/// for conditions that depend on late-bound state such as ambient context values,
/// feature flags, or other runtime information only available at request creation time.
///
- ///
- ///
- ///
+ /// The instance.
+ /// A function that evaluates to determine whether to apply the configuration.
+ /// The action to invoke when the predicate returns true.
+ /// The for method chaining.
public static HttpRequestBuilder When(
this HttpRequestBuilder builder,
Func predicate,
diff --git a/src/FluentHttpClient/FluentCookieExtensions.cs b/src/FluentHttpClient/FluentCookieExtensions.cs
index 68363e9..2bc02e6 100644
--- a/src/FluentHttpClient/FluentCookieExtensions.cs
+++ b/src/FluentHttpClient/FluentCookieExtensions.cs
@@ -8,10 +8,10 @@ public static class FluentCookieExtensions
///
/// Adds a single cookie to the request.
///
- ///
- ///
- ///
- ///
+ /// The instance.
+ /// The name of the cookie.
+ /// The value of the cookie.
+ /// The for method chaining.
public static HttpRequestBuilder WithCookie(this HttpRequestBuilder builder, string name, string value)
{
if (string.IsNullOrWhiteSpace(name))
@@ -29,9 +29,9 @@ public static HttpRequestBuilder WithCookie(this HttpRequestBuilder builder, str
///
/// Existing cookies with the same name will be overwritten.
///
- ///
- ///
- ///
+ /// The instance.
+ /// The collection of cookies as key-value pairs to add to the request.
+ /// The for method chaining.
public static HttpRequestBuilder WithCookies(
this HttpRequestBuilder builder,
IEnumerable> cookies)
diff --git a/src/FluentHttpClient/FluentHeaderExtensions.cs b/src/FluentHttpClient/FluentHeaderExtensions.cs
index 2a0a587..29de03e 100644
--- a/src/FluentHttpClient/FluentHeaderExtensions.cs
+++ b/src/FluentHttpClient/FluentHeaderExtensions.cs
@@ -16,9 +16,10 @@ public static class FluentHeaderExtensions
///
/// Adds the specified header and its value to the request.
///
- ///
- ///
- ///
+ /// The instance.
+ /// The name of the header to add.
+ /// The value of the header.
+ /// The for method chaining.
public static HttpRequestBuilder WithHeader(this HttpRequestBuilder builder, string key, string value)
{
Guard.AgainstNull(key, nameof(key));
@@ -41,9 +42,10 @@ public static HttpRequestBuilder WithHeader(this HttpRequestBuilder builder, str
///
/// Adds the specified header and its values to the request.
///
- ///
- ///
- ///
+ /// The instance.
+ /// The name of the header to add.
+ /// The collection of values for the header.
+ /// The for method chaining.
public static HttpRequestBuilder WithHeader(this HttpRequestBuilder builder, string key, IEnumerable values)
{
Guard.AgainstNull(key, nameof(key));
@@ -66,8 +68,9 @@ public static HttpRequestBuilder WithHeader(this HttpRequestBuilder builder, str
///
/// Adds the specified headers and their values to the request.
///
- ///
- ///
+ /// The instance.
+ /// The collection of headers as key-value pairs to add to the request.
+ /// The for method chaining.
public static HttpRequestBuilder WithHeaders(this HttpRequestBuilder builder, IEnumerable> headers)
{
Guard.AgainstNull(headers, nameof(headers));
@@ -97,8 +100,9 @@ public static HttpRequestBuilder WithHeaders(this HttpRequestBuilder builder, IE
///
/// Adds the specified headers and their multiple values to the request.
///
- ///
- ///
+ /// The instance.
+ /// The collection of headers where each header can have multiple values.
+ /// The for method chaining.
public static HttpRequestBuilder WithHeaders(
this HttpRequestBuilder builder,
IEnumerable>> headers)
diff --git a/src/FluentHttpClient/FluentJsonContentExtensions.cs b/src/FluentHttpClient/FluentJsonContentExtensions.cs
index 6f599f1..6fc9b57 100644
--- a/src/FluentHttpClient/FluentJsonContentExtensions.cs
+++ b/src/FluentHttpClient/FluentJsonContentExtensions.cs
@@ -20,6 +20,10 @@ public static partial class FluentJsonContentExtensions
/// Serializes the specified value as JSON using the default serializer options and sets it as the request content
/// with UTF-8 encoding and the default JSON media type.
///
+ /// The type of the value to serialize.
+ /// The instance.
+ /// The value to serialize as JSON.
+ /// The for method chaining.
public static HttpRequestBuilder WithJsonContent(
this HttpRequestBuilder builder,
T value)
@@ -34,6 +38,11 @@ public static HttpRequestBuilder WithJsonContent(
/// Serializes the specified value as JSON using the provided serializer options and sets it as the request content
/// with UTF-8 encoding and the default JSON media type.
///
+ /// The type of the value to serialize.
+ /// The instance.
+ /// The value to serialize as JSON.
+ /// The JSON serializer options to use.
+ /// The for method chaining.
public static HttpRequestBuilder WithJsonContent(
this HttpRequestBuilder builder,
T value,
@@ -49,6 +58,11 @@ public static HttpRequestBuilder WithJsonContent(
/// Serializes the specified value as JSON using the default serializer options and sets it as the request content
/// with UTF-8 encoding and the specified media type.
///
+ /// The type of the value to serialize.
+ /// The instance.
+ /// The value to serialize as JSON.
+ /// The media type string for the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithJsonContent(
this HttpRequestBuilder builder,
T value,
@@ -64,6 +78,12 @@ public static HttpRequestBuilder WithJsonContent(
/// Serializes the specified value as JSON using the provided serializer options and sets it as the request content
/// with UTF-8 encoding and the specified media type.
///
+ /// The type of the value to serialize.
+ /// The instance.
+ /// The value to serialize as JSON.
+ /// The JSON serializer options to use.
+ /// The media type string for the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithJsonContent(
this HttpRequestBuilder builder,
T value,
@@ -80,6 +100,11 @@ public static HttpRequestBuilder WithJsonContent(
/// Serializes the specified value as JSON using the default serializer options and sets it as the request content
/// with UTF-8 encoding and applies the specified content type header value.
///
+ /// The type of the value to serialize.
+ /// The instance.
+ /// The value to serialize as JSON.
+ /// The media type header value to apply to the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithJsonContent(
this HttpRequestBuilder builder,
T value,
@@ -97,6 +122,12 @@ public static HttpRequestBuilder WithJsonContent(
/// Serializes the specified value as JSON using the provided serializer options and sets it as the request content
/// with UTF-8 encoding and applies the given content type header value.
///
+ /// The type of the value to serialize.
+ /// The instance.
+ /// The value to serialize as JSON.
+ /// The JSON serializer options to use.
+ /// The media type header value to apply to the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithJsonContent(
this HttpRequestBuilder builder,
T value,
diff --git a/src/FluentHttpClient/FluentJsonContentExtensionsAot.cs b/src/FluentHttpClient/FluentJsonContentExtensionsAot.cs
index a4a004e..60cea71 100644
--- a/src/FluentHttpClient/FluentJsonContentExtensionsAot.cs
+++ b/src/FluentHttpClient/FluentJsonContentExtensionsAot.cs
@@ -13,6 +13,11 @@ public static partial class FluentJsonContentExtensions
/// Serializes using the supplied and
/// sets the JSON payload as the request content using UTF-8 and the default media type.
///
+ /// The type of the value to serialize.
+ /// The instance.
+ /// The value to serialize as JSON.
+ /// The JSON type metadata for AOT-safe serialization.
+ /// The for method chaining.
public static HttpRequestBuilder WithJsonContent(
this HttpRequestBuilder builder,
T value,
@@ -31,6 +36,11 @@ public static HttpRequestBuilder WithJsonContent(
/// Serializes using metadata from the provided
/// and sets the JSON payload as the request content.
///
+ /// The type of the value to serialize.
+ /// The instance.
+ /// The value to serialize as JSON.
+ /// The JSON serializer context containing type metadata for AOT-safe serialization.
+ /// The for method chaining.
public static HttpRequestBuilder WithJsonContent(
this HttpRequestBuilder builder,
T value,
@@ -54,6 +64,12 @@ public static HttpRequestBuilder WithJsonContent(
/// Serializes using the supplied and
/// sets the JSON payload as the request content using UTF-8 and the specified media type.
///
+ /// The type of the value to serialize.
+ /// The instance.
+ /// The value to serialize as JSON.
+ /// The JSON type metadata for AOT-safe serialization.
+ /// The media type string for the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithJsonContent(
this HttpRequestBuilder builder,
T value,
@@ -75,6 +91,12 @@ public static HttpRequestBuilder WithJsonContent(
/// and sets the JSON payload as the request content
/// using UTF-8 and the specified media type.
///
+ /// The type of the value to serialize.
+ /// The instance.
+ /// The value to serialize as JSON.
+ /// The JSON serializer context containing type metadata for AOT-safe serialization.
+ /// The media type string for the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithJsonContent(
this HttpRequestBuilder builder,
T value,
@@ -100,6 +122,12 @@ public static HttpRequestBuilder WithJsonContent(
/// Serializes using the supplied and
/// sets the JSON payload as the request content using UTF-8 and the specified content type header.
///
+ /// The type of the value to serialize.
+ /// The instance.
+ /// The value to serialize as JSON.
+ /// The JSON type metadata for AOT-safe serialization.
+ /// The media type header value to apply to the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithJsonContent(
this HttpRequestBuilder builder,
T value,
@@ -124,6 +152,12 @@ public static HttpRequestBuilder WithJsonContent(
/// and sets the JSON payload as the request content
/// using UTF-8 and the specified content type header.
///
+ /// The type of the value to serialize.
+ /// The instance.
+ /// The value to serialize as JSON.
+ /// The JSON serializer context containing type metadata for AOT-safe serialization.
+ /// The media type header value to apply to the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithJsonContent(
this HttpRequestBuilder builder,
T value,
diff --git a/src/FluentHttpClient/FluentJsonDeserialization.cs b/src/FluentHttpClient/FluentJsonDeserialization.cs
index 9bea82d..7db7d60 100644
--- a/src/FluentHttpClient/FluentJsonDeserialization.cs
+++ b/src/FluentHttpClient/FluentJsonDeserialization.cs
@@ -19,8 +19,8 @@ public static class FluentJsonDeserialization
///
/// Reads the JSON content of the response and parses it into a .
///
- ///
- ///
+ /// The HTTP response whose content will be read.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonDocument, or null if the content is empty.
public static Task ReadJsonDocumentAsync(this HttpResponseMessage response)
{
return response.ReadJsonDocumentAsync(_jsonDocumentOptions, CancellationToken.None);
@@ -30,9 +30,9 @@ public static class FluentJsonDeserialization
/// Reads the JSON content of the response and parses it into a ,
/// using the specified .
///
- ///
- ///
- ///
+ /// The HTTP response whose content will be read.
+ /// Options that control the parsing behavior.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonDocument, or null if the content is empty.
public static Task ReadJsonDocumentAsync(
this HttpResponseMessage response,
JsonDocumentOptions documentOptions)
@@ -44,9 +44,9 @@ public static class FluentJsonDeserialization
/// Reads the JSON content of the response and parses it into a ,
/// observing the provided cancellation token.
///
- ///
- ///
- ///
+ /// The HTTP response whose content will be read.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonDocument, or null if the content is empty.
public static Task ReadJsonDocumentAsync(
this HttpResponseMessage response,
CancellationToken cancellationToken)
@@ -58,10 +58,10 @@ public static class FluentJsonDeserialization
/// Reads the JSON content of the response and parses it into a ,
/// using the specified and cancellation token.
///
- ///
- ///
- ///
- ///
+ /// The HTTP response whose content will be read.
+ /// Options that control the parsing behavior.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonDocument, or null if the content is empty.
public static async Task ReadJsonDocumentAsync(
this HttpResponseMessage response,
JsonDocumentOptions documentOptions,
@@ -88,8 +88,8 @@ public static class FluentJsonDeserialization
///
/// Awaits the HTTP response task, then reads the JSON content and parses it into a .
///
- ///
- ///
+ /// A task that produces the HTTP response whose content will be read.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonDocument, or null if the content is empty.
public static Task ReadJsonDocumentAsync(this Task responseTask)
{
return responseTask.ReadJsonDocumentAsync(_jsonDocumentOptions, CancellationToken.None);
@@ -99,9 +99,9 @@ public static class FluentJsonDeserialization
/// Awaits the HTTP response task, then reads the JSON content and parses it into a ,
/// using the specified .
///
- ///
- ///
- ///
+ /// A task that produces the HTTP response whose content will be read.
+ /// Options that control the parsing behavior.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonDocument, or null if the content is empty.
public static Task ReadJsonDocumentAsync(
this Task responseTask,
JsonDocumentOptions documentOptions)
@@ -113,9 +113,9 @@ public static class FluentJsonDeserialization
/// Awaits the HTTP response task, then reads the JSON content and parses it into a ,
/// observing the provided cancellation token.
///
- ///
- ///
- ///
+ /// A task that produces the HTTP response whose content will be read.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonDocument, or null if the content is empty.
public static Task ReadJsonDocumentAsync(
this Task responseTask,
CancellationToken cancellationToken)
@@ -127,10 +127,10 @@ public static class FluentJsonDeserialization
/// Awaits the HTTP response task, then reads the JSON content and parses it into a ,
/// using the specified and cancellation token.
///
- ///
- ///
- ///
- ///
+ /// A task that produces the HTTP response whose content will be read.
+ /// Options that control the parsing behavior.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonDocument, or null if the content is empty.
public static async Task ReadJsonDocumentAsync(
this Task responseTask,
JsonDocumentOptions documentOptions,
@@ -147,7 +147,8 @@ public static class FluentJsonDeserialization
///
/// Reads the JSON content of the response and parses it into a .
///
- ///
+ /// The HTTP response whose content will be read.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonObject, or null if the content is empty.
public static Task ReadJsonObjectAsync(this HttpResponseMessage response)
{
return response.ReadJsonObjectAsync(
@@ -160,8 +161,9 @@ public static class FluentJsonDeserialization
/// Reads the JSON content of the response and parses it into a ,
/// observing the provided cancellation token.
///
- ///
- ///
+ /// The HTTP response whose content will be read.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonObject, or null if the content is empty.
public static Task ReadJsonObjectAsync(
this HttpResponseMessage response,
CancellationToken cancellationToken)
@@ -176,8 +178,9 @@ public static class FluentJsonDeserialization
/// Reads the JSON content of the response and parses it into a ,
/// using the specified .
///
- ///
- ///
+ /// The HTTP response whose content will be read.
+ /// Options that control the behavior of the JsonNode.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonObject, or null if the content is empty.
public static Task ReadJsonObjectAsync(
this HttpResponseMessage response,
JsonNodeOptions nodeOptions)
@@ -192,9 +195,10 @@ public static class FluentJsonDeserialization
/// Reads the JSON content of the response and parses it into a ,
/// using the specified and observing the provided cancellation token.
///
- ///
- ///
- ///
+ /// The HTTP response whose content will be read.
+ /// Options that control the behavior of the JsonNode.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonObject, or null if the content is empty.
public static Task ReadJsonObjectAsync(
this HttpResponseMessage response,
JsonNodeOptions nodeOptions,
@@ -210,8 +214,9 @@ public static class FluentJsonDeserialization
/// Reads the JSON content of the response and parses it into a ,
/// using the specified .
///
- ///
- ///
+ /// The HTTP response whose content will be read.
+ /// Options that control the parsing behavior.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonObject, or null if the content is empty.
public static Task ReadJsonObjectAsync(
this HttpResponseMessage response,
JsonDocumentOptions documentOptions)
@@ -226,9 +231,10 @@ public static class FluentJsonDeserialization
/// Reads the JSON content of the response and parses it into a ,
/// using the specified and observing the provided cancellation token.
///
- ///
- ///
- ///
+ /// The HTTP response whose content will be read.
+ /// Options that control the parsing behavior.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonObject, or null if the content is empty.
public static Task ReadJsonObjectAsync(
this HttpResponseMessage response,
JsonDocumentOptions documentOptions,
@@ -244,9 +250,10 @@ public static class FluentJsonDeserialization
/// Reads the JSON content of the response and parses it into a ,
/// using the specified and .
///
- ///
- ///
- ///
+ /// The HTTP response whose content will be read.
+ /// Options that control the behavior of the JsonNode.
+ /// Options that control the parsing behavior.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonObject, or null if the content is empty.
public static Task ReadJsonObjectAsync(
this HttpResponseMessage response,
JsonNodeOptions nodeOptions,
@@ -263,10 +270,11 @@ public static class FluentJsonDeserialization
/// using the specified , ,
/// and observing the provided cancellation token.
///
- ///
- ///
- ///
- ///
+ /// The HTTP response whose content will be read.
+ /// Options that control the behavior of the JsonNode.
+ /// Options that control the parsing behavior.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonObject, or null if the content is empty.
public static async Task ReadJsonObjectAsync(
this HttpResponseMessage response,
JsonNodeOptions nodeOptions,
@@ -295,7 +303,8 @@ public static class FluentJsonDeserialization
///
/// Awaits the HTTP response task, then reads the JSON content and parses it into a .
///
- ///
+ /// A task that produces the HTTP response whose content will be read.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonObject, or null if the content is empty.
public static Task ReadJsonObjectAsync(this Task responseTask)
{
return responseTask.ReadJsonObjectAsync(
@@ -308,8 +317,9 @@ public static class FluentJsonDeserialization
/// Awaits the HTTP response task, then reads the JSON content and parses it into a ,
/// observing the provided cancellation token.
///
- ///
- ///
+ /// A task that produces the HTTP response whose content will be read.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonObject, or null if the content is empty.
public static Task ReadJsonObjectAsync(
this Task responseTask,
CancellationToken cancellationToken)
@@ -324,8 +334,9 @@ public static class FluentJsonDeserialization
/// Awaits the HTTP response task, then reads the JSON content and parses it into a ,
/// using the specified .
///
- ///
- ///
+ /// A task that produces the HTTP response whose content will be read.
+ /// Options that control the behavior of the JsonNode.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonObject, or null if the content is empty.
public static Task ReadJsonObjectAsync(
this Task responseTask,
JsonNodeOptions nodeOptions)
@@ -340,9 +351,10 @@ public static class FluentJsonDeserialization
/// Awaits the HTTP response task, then reads the JSON content and parses it into a ,
/// using the specified and observing the provided cancellation token.
///
- ///
- ///
- ///
+ /// A task that produces the HTTP response whose content will be read.
+ /// Options that control the behavior of the JsonNode.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonObject, or null if the content is empty.
public static Task ReadJsonObjectAsync(
this Task responseTask,
JsonNodeOptions nodeOptions,
@@ -358,8 +370,9 @@ public static class FluentJsonDeserialization
/// Awaits the HTTP response task, then reads the JSON content and parses it into a ,
/// using the specified .
///
- ///
- ///
+ /// A task that produces the HTTP response whose content will be read.
+ /// Options that control the parsing behavior.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonObject, or null if the content is empty.
public static Task ReadJsonObjectAsync(
this Task responseTask,
JsonDocumentOptions documentOptions)
@@ -374,9 +387,10 @@ public static class FluentJsonDeserialization
/// Awaits the HTTP response task, then reads the JSON content and parses it into a ,
/// using the specified and observing the provided cancellation token.
///
- ///
- ///
- ///
+ /// A task that produces the HTTP response whose content will be read.
+ /// Options that control the parsing behavior.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonObject, or null if the content is empty.
public static Task ReadJsonObjectAsync(
this Task responseTask,
JsonDocumentOptions documentOptions,
@@ -392,9 +406,10 @@ public static class FluentJsonDeserialization
/// Awaits the HTTP response task, then reads the JSON content and parses it into a ,
/// using the specified and .
///
- ///
- ///
- ///
+ /// A task that produces the HTTP response whose content will be read.
+ /// Options that control the behavior of the JsonNode.
+ /// Options that control the parsing behavior.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonObject, or null if the content is empty.
public static Task ReadJsonObjectAsync(
this Task responseTask,
JsonNodeOptions nodeOptions,
@@ -411,10 +426,11 @@ public static class FluentJsonDeserialization
/// using the specified , ,
/// and observing the provided cancellation token.
///
- ///
- ///
- ///
- ///
+ /// A task that produces the HTTP response whose content will be read.
+ /// Options that control the behavior of the JsonNode.
+ /// Options that control the parsing behavior.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the parsed JsonObject, or null if the content is empty.
public static async Task ReadJsonObjectAsync(
this Task responseTask,
JsonNodeOptions nodeOptions,
diff --git a/src/FluentHttpClient/FluentJsonSerializer.cs b/src/FluentHttpClient/FluentJsonSerializer.cs
index 2d542a0..0fdc7cb 100644
--- a/src/FluentHttpClient/FluentJsonSerializer.cs
+++ b/src/FluentHttpClient/FluentJsonSerializer.cs
@@ -4,6 +4,9 @@
namespace FluentHttpClient;
+///
+/// Provides default JSON serialization settings and constants for the FluentHttpClient library.
+///
[ExcludeFromCodeCoverage]
internal static class FluentJsonSerializer
{
diff --git a/src/FluentHttpClient/FluentJsonTypedDeserialization.cs b/src/FluentHttpClient/FluentJsonTypedDeserialization.cs
index 34efebe..558e350 100644
--- a/src/FluentHttpClient/FluentJsonTypedDeserialization.cs
+++ b/src/FluentHttpClient/FluentJsonTypedDeserialization.cs
@@ -17,9 +17,9 @@ public static partial class FluentJsonTypedDeserialization
///
/// Reads the JSON content of the response and deserializes it to .
///
- ///
- ///
- ///
+ /// The type to deserialize the JSON content into.
+ /// The HTTP response whose content will be read.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or the default value if the content is empty.
public static Task ReadJsonAsync(this HttpResponseMessage response)
{
return response.ReadJsonAsync(
@@ -31,10 +31,10 @@ public static partial class FluentJsonTypedDeserialization
/// Reads the JSON content of the response and deserializes it to ,
/// using the specified serializer options.
///
- ///
- ///
- ///
- ///
+ /// The type to deserialize the JSON content into.
+ /// The HTTP response whose content will be read.
+ /// Options to control the deserialization behavior.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or the default value if the content is empty.
public static Task ReadJsonAsync(
this HttpResponseMessage response,
JsonSerializerOptions? options)
@@ -46,10 +46,10 @@ public static partial class FluentJsonTypedDeserialization
/// Reads the JSON content of the response and deserializes it to ,
/// observing the provided cancellation token.
///
- ///
- ///
- ///
- ///
+ /// The type to deserialize the JSON content into.
+ /// The HTTP response whose content will be read.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or the default value if the content is empty.
public static Task ReadJsonAsync(
this HttpResponseMessage response,
CancellationToken cancellationToken)
@@ -63,11 +63,11 @@ public static partial class FluentJsonTypedDeserialization
/// Reads the JSON content of the response and deserializes it to ,
/// using the specified serializer options and cancellation token.
///
- ///
- ///
- ///
- ///
- ///
+ /// The type to deserialize the JSON content into.
+ /// The HTTP response whose content will be read.
+ /// Options to control the deserialization behavior.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or the default value if the content is empty.
public static async Task ReadJsonAsync(
this HttpResponseMessage response,
JsonSerializerOptions? options,
@@ -100,9 +100,9 @@ public static partial class FluentJsonTypedDeserialization
///
/// Awaits the HTTP response task, then reads and deserializes the JSON content to .
///
- ///
- ///
- ///
+ /// The type to deserialize the JSON content into.
+ /// A task that produces the HTTP response whose content will be read.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or the default value if the content is empty.
public static Task ReadJsonAsync(this Task responseTask)
{
return responseTask.ReadJsonAsync(
@@ -114,10 +114,10 @@ public static partial class FluentJsonTypedDeserialization
/// Awaits the HTTP response task, then reads and deserializes the JSON content to ,
/// using the specified serializer options.
///
- ///
- ///
- ///
- ///
+ /// The type to deserialize the JSON content into.
+ /// A task that produces the HTTP response whose content will be read.
+ /// Options to control the deserialization behavior.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or the default value if the content is empty.
public static Task ReadJsonAsync(
this Task responseTask,
JsonSerializerOptions? options)
@@ -129,10 +129,10 @@ public static partial class FluentJsonTypedDeserialization
/// Awaits the HTTP response task, then reads and deserializes the JSON content to ,
/// observing the provided cancellation token.
///
- ///
- ///
- ///
- ///
+ /// The type to deserialize the JSON content into.
+ /// A task that produces the HTTP response whose content will be read.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or the default value if the content is empty.
public static Task ReadJsonAsync(
this Task responseTask,
CancellationToken cancellationToken)
@@ -146,11 +146,11 @@ public static partial class FluentJsonTypedDeserialization
/// Awaits the HTTP response task, then reads and deserializes the JSON content to ,
/// using the specified serializer options and cancellation token.
///
- ///
- ///
- ///
- ///
- ///
+ /// The type to deserialize the JSON content into.
+ /// A task that produces the HTTP response whose content will be read.
+ /// Options to control the deserialization behavior.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or the default value if the content is empty.
public static async Task ReadJsonAsync(
this Task responseTask,
JsonSerializerOptions? options,
diff --git a/src/FluentHttpClient/FluentJsonTypedDeserializationAot.cs b/src/FluentHttpClient/FluentJsonTypedDeserializationAot.cs
index 0d39786..e4e681a 100644
--- a/src/FluentHttpClient/FluentJsonTypedDeserializationAot.cs
+++ b/src/FluentHttpClient/FluentJsonTypedDeserializationAot.cs
@@ -11,6 +11,11 @@ public static partial class FluentJsonTypedDeserialization
/// Reads the JSON content of the response and deserializes it to
/// using the provided .
///
+ /// The type to deserialize the JSON content into.
+ /// The HTTP response whose content will be read.
+ /// The JSON type metadata for AOT-safe deserialization.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or the default value if the content is empty.
public static async Task ReadJsonAsync(
this HttpResponseMessage response,
JsonTypeInfo jsonTypeInfo,
@@ -37,6 +42,11 @@ public static partial class FluentJsonTypedDeserialization
/// Reads the JSON content of the response and deserializes it to
/// using the provided .
///
+ /// The type to deserialize the JSON content into.
+ /// The HTTP response whose content will be read.
+ /// The JSON serializer context containing type metadata for AOT-safe deserialization.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or the default value if the content is empty.
public static Task ReadJsonAsync(
this HttpResponseMessage response,
JsonSerializerContext context,
@@ -58,6 +68,11 @@ public static partial class FluentJsonTypedDeserialization
/// Awaits the HTTP response task, then reads and deserializes the JSON content to
/// using the provided .
///
+ /// The type to deserialize the JSON content into.
+ /// A task that produces the HTTP response whose content will be read.
+ /// The JSON type metadata for AOT-safe deserialization.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or the default value if the content is empty.
public static async Task ReadJsonAsync(
this Task responseTask,
JsonTypeInfo jsonTypeInfo,
@@ -77,6 +92,11 @@ public static partial class FluentJsonTypedDeserialization
/// Awaits the HTTP response task, then reads and deserializes the JSON content to
/// using the provided .
///
+ /// The type to deserialize the JSON content into.
+ /// A task that produces the HTTP response whose content will be read.
+ /// The JSON serializer context containing type metadata for AOT-safe deserialization.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or the default value if the content is empty.
public static async Task ReadJsonAsync(
this Task responseTask,
JsonSerializerContext context,
diff --git a/src/FluentHttpClient/FluentOptionsExtensions.cs b/src/FluentHttpClient/FluentOptionsExtensions.cs
index 0255290..9642af1 100644
--- a/src/FluentHttpClient/FluentOptionsExtensions.cs
+++ b/src/FluentHttpClient/FluentOptionsExtensions.cs
@@ -9,8 +9,9 @@ public static class FluentOptionsExtensions
///
/// Adds a configurator for modifying the collection.
///
- ///
- ///
+ /// The instance.
+ /// The action to configure the request options.
+ /// The for method chaining.
public static HttpRequestBuilder ConfigureOptions(this HttpRequestBuilder builder, Action action)
{
Guard.AgainstNull(action, nameof(action));
@@ -22,9 +23,11 @@ public static HttpRequestBuilder ConfigureOptions(this HttpRequestBuilder builde
///
/// Sets a typed option value on the collection.
///
- ///
- ///
- ///
+ /// The type of the option value.
+ /// The instance.
+ /// The key identifying the option to set.
+ /// The value to set for the option.
+ /// The for method chaining.
public static HttpRequestBuilder WithOption(this HttpRequestBuilder builder, HttpRequestOptionsKey key, T value)
{
builder.OptionConfigurators.Add(options =>
diff --git a/src/FluentHttpClient/FluentQueryParametersExtensions.cs b/src/FluentHttpClient/FluentQueryParametersExtensions.cs
index 1a7e6be..24804cb 100644
--- a/src/FluentHttpClient/FluentQueryParametersExtensions.cs
+++ b/src/FluentHttpClient/FluentQueryParametersExtensions.cs
@@ -12,10 +12,10 @@ public static class FluentQueryParameterExtensions
///
/// Adds a query string parameter with the specified key and value.
///
- ///
- ///
- ///
- ///
+ /// The instance.
+ /// The query parameter key.
+ /// The query parameter value.
+ /// The for method chaining.
public static HttpRequestBuilder WithQueryParameter(
this HttpRequestBuilder builder,
string key,
@@ -30,10 +30,10 @@ public static HttpRequestBuilder WithQueryParameter(
///
/// Adds a query string parameter with the specified key and a value converted using .
///
- ///
- ///
- ///
- ///
+ /// The instance.
+ /// The query parameter key.
+ /// The query parameter value that will be converted to a string.
+ /// The for method chaining.
public static HttpRequestBuilder WithQueryParameter(
this HttpRequestBuilder builder,
string key,
@@ -48,10 +48,10 @@ public static HttpRequestBuilder WithQueryParameter(
///
/// Adds one or more query string parameter values for the specified key.
///
- ///
- ///
- ///
- ///
+ /// The instance.
+ /// The query parameter key.
+ /// The collection of values for the parameter.
+ /// The for method chaining.
public static HttpRequestBuilder WithQueryParameter(
this HttpRequestBuilder builder,
string key,
@@ -67,10 +67,10 @@ public static HttpRequestBuilder WithQueryParameter(
///
/// Adds one or more query string parameter values for the specified key, converting each value using .
///
- ///
- ///
- ///
- ///
+ /// The instance.
+ /// The query parameter key.
+ /// The collection of values that will be converted to strings.
+ /// The for method chaining.
public static HttpRequestBuilder WithQueryParameter(
this HttpRequestBuilder builder,
string key,
@@ -93,9 +93,9 @@ public static HttpRequestBuilder WithQueryParameter(
///
/// Adds multiple query string parameters from the specified sequence of key/value pairs.
///
- ///
- ///
- ///
+ /// The instance.
+ /// The collection of query parameters as key-value pairs.
+ /// The for method chaining.
public static HttpRequestBuilder WithQueryParameters(
this HttpRequestBuilder builder,
IEnumerable> parameters)
@@ -113,9 +113,9 @@ public static HttpRequestBuilder WithQueryParameters(
///
/// Adds multiple query string parameters from the specified sequence of key/value pairs, converting values using .
///
- ///
- ///
- ///
+ /// The instance.
+ /// The collection of query parameters whose values will be converted to strings.
+ /// The for method chaining.
public static HttpRequestBuilder WithQueryParameters(
this HttpRequestBuilder builder,
IEnumerable> parameters)
@@ -133,9 +133,9 @@ public static HttpRequestBuilder WithQueryParameters(
///
/// Adds multiple query string parameters from the specified sequence of keys and value sequences.
///
- ///
- ///
- ///
+ /// The instance.
+ /// The collection of query parameters where each can have multiple values.
+ /// The for method chaining.
public static HttpRequestBuilder WithQueryParameters(
this HttpRequestBuilder builder,
IEnumerable>> parameters)
@@ -153,9 +153,9 @@ public static HttpRequestBuilder WithQueryParameters(
///
/// Adds multiple query string parameters from the specified sequence of keys and value sequences, converting values using .
///
- ///
- ///
- ///
+ /// The instance.
+ /// The collection of query parameters where each can have multiple values that will be converted to strings.
+ /// The for method chaining.
public static HttpRequestBuilder WithQueryParameters(
this HttpRequestBuilder builder,
IEnumerable>> parameters)
@@ -182,10 +182,10 @@ public static HttpRequestBuilder WithQueryParameters(
///
/// Adds a query string parameter with the specified key and value when the value is not null.
///
- ///
- ///
- ///
- ///
+ /// The instance.
+ /// The query parameter key.
+ /// The query parameter value, which is only added if not null.
+ /// The for method chaining.
public static HttpRequestBuilder WithQueryParameterIfNotNull(
this HttpRequestBuilder builder,
string key,
@@ -198,10 +198,10 @@ public static HttpRequestBuilder WithQueryParameterIfNotNull(
///
/// Adds a query string parameter with the specified key and a value converted using when the value is not null.
///
- ///
- ///
- ///
- ///
+ /// The instance.
+ /// The query parameter key.
+ /// The query parameter value that will be converted to a string, only added if not null.
+ /// The for method chaining.
public static HttpRequestBuilder WithQueryParameterIfNotNull(
this HttpRequestBuilder builder,
string key,
diff --git a/src/FluentHttpClient/FluentSendExtensions.cs b/src/FluentHttpClient/FluentSendExtensions.cs
index cd3fdd6..0fb252d 100644
--- a/src/FluentHttpClient/FluentSendExtensions.cs
+++ b/src/FluentHttpClient/FluentSendExtensions.cs
@@ -11,7 +11,8 @@ public static class FluentSendExtensions
///
/// Sends an HTTP DELETE request using the configured .
///
- ///
+ /// The instance.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task DeleteAsync(this HttpRequestBuilder builder)
{
return builder.SendAsync(HttpMethod.Delete);
@@ -20,8 +21,9 @@ public static Task DeleteAsync(this HttpRequestBuilder buil
///
/// Sends an HTTP DELETE request using the specified .
///
- ///
- ///
+ /// The instance.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task DeleteAsync(
this HttpRequestBuilder builder,
CancellationToken cancellationToken)
@@ -32,8 +34,9 @@ public static Task DeleteAsync(
///
/// Sends an HTTP DELETE request using the specified .
///
- ///
- ///
+ /// The instance.
+ /// Indicates when the operation should complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task DeleteAsync(
this HttpRequestBuilder builder,
HttpCompletionOption completionOption)
@@ -44,9 +47,10 @@ public static Task DeleteAsync(
///
/// Sends an HTTP DELETE request using the specified and .
///
- ///
- ///
- ///
+ /// The instance.
+ /// Indicates when the operation should complete.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task DeleteAsync(
this HttpRequestBuilder builder,
HttpCompletionOption completionOption,
@@ -60,7 +64,8 @@ public static Task DeleteAsync(
///
/// Sends an HTTP GET request using the configured .
///
- ///
+ /// The instance.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task GetAsync(this HttpRequestBuilder builder)
{
return builder.SendAsync(HttpMethod.Get);
@@ -69,8 +74,9 @@ public static Task GetAsync(this HttpRequestBuilder builder
///
/// Sends an HTTP GET request using the specified .
///
- ///
- ///
+ /// The instance.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task GetAsync(
this HttpRequestBuilder builder,
CancellationToken cancellationToken)
@@ -81,8 +87,9 @@ public static Task GetAsync(
///
/// Sends an HTTP GET request using the specified .
///
- ///
- ///
+ /// The instance.
+ /// Indicates when the operation should complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task GetAsync(
this HttpRequestBuilder builder,
HttpCompletionOption completionOption)
@@ -93,9 +100,10 @@ public static Task GetAsync(
///
/// Sends an HTTP GET request using the specified and .
///
- ///
- ///
- ///
+ /// The instance.
+ /// Indicates when the operation should complete.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task GetAsync(
this HttpRequestBuilder builder,
HttpCompletionOption completionOption,
@@ -109,7 +117,8 @@ public static Task GetAsync(
///
/// Sends an HTTP HEAD request using the configured .
///
- ///
+ /// The instance.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task HeadAsync(this HttpRequestBuilder builder)
{
return builder.SendAsync(HttpMethod.Head);
@@ -118,8 +127,9 @@ public static Task HeadAsync(this HttpRequestBuilder builde
///
/// Sends an HTTP HEAD request using the specified .
///
- ///
- ///
+ /// The instance.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task HeadAsync(
this HttpRequestBuilder builder,
CancellationToken cancellationToken)
@@ -130,8 +140,9 @@ public static Task HeadAsync(
///
/// Sends an HTTP HEAD request using the specified .
///
- ///
- ///
+ /// The instance.
+ /// Indicates when the operation should complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task HeadAsync(
this HttpRequestBuilder builder,
HttpCompletionOption completionOption)
@@ -142,9 +153,10 @@ public static Task HeadAsync(
///
/// Sends an HTTP HEAD request using the specified and .
///
- ///
- ///
- ///
+ /// The instance.
+ /// Indicates when the operation should complete.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task HeadAsync(
this HttpRequestBuilder builder,
HttpCompletionOption completionOption,
@@ -158,7 +170,8 @@ public static Task HeadAsync(
///
/// Sends an HTTP OPTIONS request using the configured .
///
- ///
+ /// The instance.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task OptionsAsync(this HttpRequestBuilder builder)
{
return builder.SendAsync(HttpMethod.Options);
@@ -167,8 +180,9 @@ public static Task OptionsAsync(this HttpRequestBuilder bui
///
/// Sends an HTTP OPTIONS request using the specified .
///
- ///
- ///
+ /// The instance.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task OptionsAsync(
this HttpRequestBuilder builder,
CancellationToken cancellationToken)
@@ -179,8 +193,9 @@ public static Task OptionsAsync(
///
/// Sends an HTTP OPTIONS request using the specified .
///
- ///
- ///
+ /// The instance.
+ /// Indicates when the operation should complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task OptionsAsync(
this HttpRequestBuilder builder,
HttpCompletionOption completionOption)
@@ -191,9 +206,10 @@ public static Task OptionsAsync(
///
/// Sends an HTTP OPTIONS request using the specified and .
///
- ///
- ///
- ///
+ /// The instance.
+ /// Indicates when the operation should complete.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task OptionsAsync(
this HttpRequestBuilder builder,
HttpCompletionOption completionOption,
@@ -207,7 +223,8 @@ public static Task OptionsAsync(
///
/// Sends an HTTP PATCH request using the configured .
///
- ///
+ /// The instance.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task PatchAsync(this HttpRequestBuilder builder)
{
#if NETSTANDARD2_0
@@ -220,8 +237,9 @@ public static Task PatchAsync(this HttpRequestBuilder build
///
/// Sends an HTTP PATCH request using the specified .
///
- ///
- ///
+ /// The instance.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task PatchAsync(
this HttpRequestBuilder builder,
CancellationToken cancellationToken)
@@ -236,8 +254,9 @@ public static Task PatchAsync(
///
/// Sends an HTTP PATCH request using the specified .
///
- ///
- ///
+ /// The instance.
+ /// Indicates when the operation should complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task PatchAsync(
this HttpRequestBuilder builder,
HttpCompletionOption completionOption)
@@ -252,9 +271,10 @@ public static Task PatchAsync(
///
/// Sends an HTTP PATCH request using the specified and .
///
- ///
- ///
- ///
+ /// The instance.
+ /// Indicates when the operation should complete.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task PatchAsync(
this HttpRequestBuilder builder,
HttpCompletionOption completionOption,
@@ -272,7 +292,8 @@ public static Task PatchAsync(
///
/// Sends an HTTP POST request using the configured .
///
- ///
+ /// The instance.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task PostAsync(this HttpRequestBuilder builder)
{
return builder.SendAsync(HttpMethod.Post);
@@ -281,8 +302,9 @@ public static Task PostAsync(this HttpRequestBuilder builde
///
/// Sends an HTTP POST request using the specified .
///
- ///
- ///
+ /// The instance.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task PostAsync(
this HttpRequestBuilder builder,
CancellationToken cancellationToken)
@@ -293,8 +315,9 @@ public static Task PostAsync(
///
/// Sends an HTTP POST request using the specified .
///
- ///
- ///
+ /// The instance.
+ /// Indicates when the operation should complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task PostAsync(
this HttpRequestBuilder builder,
HttpCompletionOption completionOption)
@@ -305,9 +328,10 @@ public static Task PostAsync(
///
/// Sends an HTTP POST request using the specified and .
///
- ///
- ///
- ///
+ /// The instance.
+ /// Indicates when the operation should complete.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task PostAsync(
this HttpRequestBuilder builder,
HttpCompletionOption completionOption,
@@ -321,7 +345,8 @@ public static Task PostAsync(
///
/// Sends an HTTP PUT request using the configured .
///
- ///
+ /// The instance.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task PutAsync(this HttpRequestBuilder builder)
{
return builder.SendAsync(HttpMethod.Put);
@@ -330,8 +355,9 @@ public static Task PutAsync(this HttpRequestBuilder builder
///
/// Sends an HTTP PUT request using the specified .
///
- ///
- ///
+ /// The instance.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task PutAsync(
this HttpRequestBuilder builder,
CancellationToken cancellationToken)
@@ -342,8 +368,9 @@ public static Task PutAsync(
///
/// Sends an HTTP PUT request using the specified .
///
- ///
- ///
+ /// The instance.
+ /// Indicates when the operation should complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task PutAsync(
this HttpRequestBuilder builder,
HttpCompletionOption completionOption)
@@ -354,9 +381,10 @@ public static Task PutAsync(
///
/// Sends an HTTP PUT request using the specified and .
///
- ///
- ///
- ///
+ /// The instance.
+ /// Indicates when the operation should complete.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the HTTP response message.
public static Task PutAsync(
this HttpRequestBuilder builder,
HttpCompletionOption completionOption,
diff --git a/src/FluentHttpClient/FluentVersionExtensions.cs b/src/FluentHttpClient/FluentVersionExtensions.cs
index c3f74a3..6b1726b 100644
--- a/src/FluentHttpClient/FluentVersionExtensions.cs
+++ b/src/FluentHttpClient/FluentVersionExtensions.cs
@@ -9,9 +9,9 @@ public static class FluentVersionExtensions
///
/// Sets the HTTP message version using a version string such as "1.1" or "2.0".
///
- ///
- ///
- ///
+ /// The instance.
+ /// The HTTP version as a string (e.g., "1.1", "2.0").
+ /// The for method chaining.
public static HttpRequestBuilder UsingVersion(this HttpRequestBuilder builder, string version)
{
if (string.IsNullOrWhiteSpace(version))
@@ -33,10 +33,10 @@ public static HttpRequestBuilder UsingVersion(this HttpRequestBuilder builder, s
///
/// Sets the HTTP message version using the specified major and minor components.
///
- ///
- ///
- ///
- ///
+ /// The instance.
+ /// The major version number.
+ /// The minor version number.
+ /// The for method chaining.
public static HttpRequestBuilder UsingVersion(this HttpRequestBuilder builder, int major, int minor)
{
builder.Version = new Version(major, minor);
@@ -46,9 +46,9 @@ public static HttpRequestBuilder UsingVersion(this HttpRequestBuilder builder, i
///
/// Sets the HTTP message version.
///
- ///
- ///
- ///
+ /// The instance.
+ /// The HTTP version to use.
+ /// The for method chaining.
public static HttpRequestBuilder UsingVersion(this HttpRequestBuilder builder, Version version)
{
if (version is null) throw new ArgumentNullException(nameof(version));
@@ -63,10 +63,10 @@ public static HttpRequestBuilder UsingVersion(this HttpRequestBuilder builder, V
/// is interpreted and how the final HTTP version
/// is negotiated with the server.
///
- ///
- ///
- ///
- ///
+ /// The instance.
+ /// The HTTP version as a string (e.g., "1.1", "2.0").
+ /// The version policy to use for negotiation.
+ /// The for method chaining.
public static HttpRequestBuilder UsingVersion(this HttpRequestBuilder builder, string version, HttpVersionPolicy policy)
{
builder.UsingVersion(version);
@@ -79,10 +79,10 @@ public static HttpRequestBuilder UsingVersion(this HttpRequestBuilder builder, s
/// is interpreted and how the final HTTP version
/// is negotiated with the server.
///
- ///
- ///
- ///
- ///
+ /// The instance.
+ /// The HTTP version to use.
+ /// The version policy to use for negotiation.
+ /// The for method chaining.
public static HttpRequestBuilder UsingVersion(this HttpRequestBuilder builder, Version version, HttpVersionPolicy policy)
{
if (version is null) throw new ArgumentNullException(nameof(version));
@@ -97,9 +97,9 @@ public static HttpRequestBuilder UsingVersion(this HttpRequestBuilder builder, V
/// is interpreted and how the final HTTP version
/// is negotiated with the server.
///
- ///
- ///
- ///
+ /// The instance.
+ /// The version policy to use for negotiation.
+ /// The for method chaining.
public static HttpRequestBuilder UsingVersionPolicy(this HttpRequestBuilder builder, HttpVersionPolicy policy)
{
builder.VersionPolicy = policy;
diff --git a/src/FluentHttpClient/FluentXmlContentExtensions.cs b/src/FluentHttpClient/FluentXmlContentExtensions.cs
index 33c7956..1c77d97 100644
--- a/src/FluentHttpClient/FluentXmlContentExtensions.cs
+++ b/src/FluentHttpClient/FluentXmlContentExtensions.cs
@@ -5,18 +5,25 @@
namespace FluentHttpClient;
+///
+/// Fluent extension methods for adding XML content to the .
+///
#if NET7_0_OR_GREATER
[RequiresDynamicCode("XmlSerializer uses dynamic code generation which is not supported with Native AOT.")]
#endif
#if NET6_0_OR_GREATER
[RequiresUnreferencedCode("XML serialization using XmlSerializer may be incompatible with trimming. Ensure all required members are preserved or use these APIs only in non-trimmed scenarios.")]
#endif
-internal static class FluentXmlContentExtensions
+public static class FluentXmlContentExtensions
{
///
/// Serializes the specified value as XML using the default settings and sets it as the request content
/// with UTF-8 encoding and the default XML media type.
///
+ /// The type of the value to serialize.
+ /// The instance.
+ /// The value to serialize as XML.
+ /// The for method chaining.
public static HttpRequestBuilder WithXmlContent(
this HttpRequestBuilder builder,
T obj)
@@ -31,6 +38,11 @@ public static HttpRequestBuilder WithXmlContent(
/// Serializes the specified value as XML using the provided settings and sets it as the request content
/// with the encoding derived from the provided and the default XML media type.
///
+ /// The type of the value to serialize.
+ /// The instance.
+ /// The value to serialize as XML.
+ /// The XML writer settings to use during serialization.
+ /// The for method chaining.
public static HttpRequestBuilder WithXmlContent(
this HttpRequestBuilder builder,
T obj,
@@ -47,6 +59,11 @@ public static HttpRequestBuilder WithXmlContent(
/// Serializes the specified value as XML using the default settings and sets it as the request content
/// with UTF-8 encoding and the specified media type.
///
+ /// The type of the value to serialize.
+ /// The instance.
+ /// The value to serialize as XML.
+ /// The media type string for the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithXmlContent(
this HttpRequestBuilder builder,
T obj,
@@ -62,6 +79,12 @@ public static HttpRequestBuilder WithXmlContent(
/// Serializes the specified value as XML using the provided settings and sets it as the request content
/// with the encoding derived from the provided and the specified media type.
///
+ /// The type of the value to serialize.
+ /// The instance.
+ /// The value to serialize as XML.
+ /// The XML writer settings to use during serialization.
+ /// The media type string for the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithXmlContent(
this HttpRequestBuilder builder,
T obj,
@@ -79,6 +102,11 @@ public static HttpRequestBuilder WithXmlContent(
/// Serializes the specified value as XML using the default settings and sets it as the request content
/// with UTF-8 encoding and applies the specified .
///
+ /// The type of the value to serialize.
+ /// The instance.
+ /// The value to serialize as XML.
+ /// The media type header value to apply to the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithXmlContent(
this HttpRequestBuilder builder,
T obj,
@@ -97,6 +125,12 @@ public static HttpRequestBuilder WithXmlContent(
/// with the encoding derived from the provided and applies the given
/// .
///
+ /// The type of the value to serialize.
+ /// The instance.
+ /// The value to serialize as XML.
+ /// The XML writer settings to use during serialization.
+ /// The media type header value to apply to the content.
+ /// The for method chaining.
public static HttpRequestBuilder WithXmlContent(
this HttpRequestBuilder builder,
T obj,
diff --git a/src/FluentHttpClient/FluentXmlDeserialization.cs b/src/FluentHttpClient/FluentXmlDeserialization.cs
index 029defd..c8e2c81 100644
--- a/src/FluentHttpClient/FluentXmlDeserialization.cs
+++ b/src/FluentHttpClient/FluentXmlDeserialization.cs
@@ -10,7 +10,8 @@ public static class FluentXmlDeserialization
///
/// Reads the response content as XML and parses it into an .
///
- ///
+ /// The HTTP response whose content will be read.
+ /// A task that represents the asynchronous operation. The task result contains the parsed XElement, or null if the content is empty.
public static Task ReadXmlElementAsync(
this HttpResponseMessage response)
{
@@ -21,8 +22,9 @@ public static class FluentXmlDeserialization
/// Reads the response content as XML and parses it into an
/// using the provided .
///
- ///
- ///
+ /// The HTTP response whose content will be read.
+ /// Options that control how the XML is loaded.
+ /// A task that represents the asynchronous operation. The task result contains the parsed XElement, or null if the content is empty.
public static Task ReadXmlElementAsync(
this HttpResponseMessage response,
LoadOptions options)
@@ -34,8 +36,9 @@ public static class FluentXmlDeserialization
/// Reads the response content as XML and parses it into an ,
/// honoring the provided .
///
- ///
- ///
+ /// The HTTP response whose content will be read.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the parsed XElement, or null if the content is empty.
public static Task ReadXmlElementAsync(
this HttpResponseMessage response,
CancellationToken token)
@@ -47,9 +50,10 @@ public static class FluentXmlDeserialization
/// Reads the response content as XML and parses it into an
/// using the provided and .
///
- ///
- ///
- ///
+ /// The HTTP response whose content will be read.
+ /// Options that control how the XML is loaded.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the parsed XElement, or null if the content is empty.
public static Task ReadXmlElementAsync(
this HttpResponseMessage response,
LoadOptions options,
@@ -61,7 +65,8 @@ public static class FluentXmlDeserialization
///
/// Awaits the response task, then reads and parses the XML content into an .
///
- ///
+ /// A task that produces the HTTP response whose content will be read.
+ /// A task that represents the asynchronous operation. The task result contains the parsed XElement, or null if the content is empty.
public static Task ReadXmlElementAsync(
this Task responseMessage)
{
@@ -73,8 +78,9 @@ public static class FluentXmlDeserialization
/// Awaits the response task, then reads and parses the XML content into an
/// using the provided .
///
- ///
- ///
+ /// A task that produces the HTTP response whose content will be read.
+ /// Options that control how the XML is loaded.
+ /// A task that represents the asynchronous operation. The task result contains the parsed XElement, or null if the content is empty.
public static Task ReadXmlElementAsync(
this Task responseMessage,
LoadOptions options)
@@ -87,8 +93,9 @@ public static class FluentXmlDeserialization
/// Awaits the response task, then reads and parses the XML content into an ,
/// honoring the provided .
///
- ///
- ///
+ /// A task that produces the HTTP response whose content will be read.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the parsed XElement, or null if the content is empty.
public static Task ReadXmlElementAsync(
this Task responseMessage,
CancellationToken token)
@@ -101,9 +108,10 @@ public static class FluentXmlDeserialization
/// Awaits the response task, then reads and parses the XML content into an
/// using the provided and .
///
- ///
- ///
- ///
+ /// A task that produces the HTTP response whose content will be read.
+ /// Options that control how the XML is loaded.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the parsed XElement, or null if the content is empty.
public static Task ReadXmlElementAsync(
this Task responseMessage,
LoadOptions options,
diff --git a/src/FluentHttpClient/FluentXmlSerializer.cs b/src/FluentHttpClient/FluentXmlSerializer.cs
index 5e761c8..4a21f71 100644
--- a/src/FluentHttpClient/FluentXmlSerializer.cs
+++ b/src/FluentHttpClient/FluentXmlSerializer.cs
@@ -7,6 +7,9 @@
namespace FluentHttpClient;
+///
+/// Provides internal XML serialization and deserialization functionality using XmlSerializer.
+///
internal static class FluentXmlSerializer
{
private static readonly ConcurrentDictionary SerializerCache = new();
@@ -106,15 +109,26 @@ public static string Serialize(T obj, XmlWriterSettings settings)
}
}
+///
+/// A specialized that supports custom encoding for XML serialization.
+///
internal sealed class XmlStringWriter : StringWriter
{
private readonly Encoding _encoding;
+ ///
+ /// Initializes a new instance of the class with the specified format provider and encoding.
+ ///
+ /// An object that controls formatting.
+ /// The character encoding to use.
public XmlStringWriter(IFormatProvider formatProvider, Encoding encoding)
: base(formatProvider)
{
_encoding = encoding;
}
+ ///
+ /// Gets the encoding for this string writer.
+ ///
public override Encoding Encoding => _encoding;
}
diff --git a/src/FluentHttpClient/FluentXmlTypedDeserialization.cs b/src/FluentHttpClient/FluentXmlTypedDeserialization.cs
index 2df9072..602ecfe 100644
--- a/src/FluentHttpClient/FluentXmlTypedDeserialization.cs
+++ b/src/FluentHttpClient/FluentXmlTypedDeserialization.cs
@@ -17,8 +17,9 @@ public static class FluentXmlTypedDeserialization
///
/// Reads the response content as XML and deserializes it into the specified type.
///
- ///
- ///
+ /// The type to deserialize the XML content into.
+ /// The HTTP response whose content will be read.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or null if the content is empty.
public static Task ReadXmlAsync(
this HttpResponseMessage response)
where T : class
@@ -30,9 +31,10 @@ public static class FluentXmlTypedDeserialization
/// Reads the response content as XML and deserializes it into the specified type
/// using the provided .
///
- ///
- ///
- ///
+ /// The type to deserialize the XML content into.
+ /// The HTTP response whose content will be read.
+ /// The XML reader settings to use during deserialization.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or null if the content is empty.
public static Task ReadXmlAsync(
this HttpResponseMessage response,
XmlReaderSettings settings)
@@ -46,9 +48,10 @@ public static class FluentXmlTypedDeserialization
/// Reads the response content as XML and deserializes it into the specified type,
/// honoring the provided .
///
- ///
- ///
- ///
+ /// The type to deserialize the XML content into.
+ /// The HTTP response whose content will be read.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or null if the content is empty.
public static Task ReadXmlAsync(
this HttpResponseMessage response,
CancellationToken token)
@@ -61,10 +64,11 @@ public static class FluentXmlTypedDeserialization
/// Reads the response content as XML and deserializes it into the specified type
/// using the provided and .
///
- ///
- ///
- ///
- ///
+ /// The type to deserialize the XML content into.
+ /// The HTTP response whose content will be read.
+ /// The XML reader settings to use during deserialization.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or null if the content is empty.
public static Task ReadXmlAsync(
this HttpResponseMessage response,
XmlReaderSettings settings,
@@ -78,8 +82,9 @@ public static class FluentXmlTypedDeserialization
///
/// Awaits the response task, then reads and deserializes the XML content into the specified type.
///
- ///
- ///
+ /// The type to deserialize the XML content into.
+ /// A task that produces the HTTP response whose content will be read.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or null if the content is empty.
public static Task ReadXmlAsync(
this Task responseMessage)
where T : class
@@ -92,9 +97,10 @@ public static class FluentXmlTypedDeserialization
/// Awaits the response task, then reads and deserializes the XML content into the specified type
/// using the provided .
///
- ///
- ///
- ///
+ /// The type to deserialize the XML content into.
+ /// A task that produces the HTTP response whose content will be read.
+ /// The XML reader settings to use during deserialization.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or null if the content is empty.
public static Task ReadXmlAsync(
this Task responseMessage,
XmlReaderSettings settings)
@@ -109,9 +115,10 @@ public static class FluentXmlTypedDeserialization
/// Awaits the response task, then reads and deserializes the XML content into the specified type,
/// honoring the provided .
///
- ///
- ///
- ///
+ /// The type to deserialize the XML content into.
+ /// A task that produces the HTTP response whose content will be read.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or null if the content is empty.
public static Task ReadXmlAsync(
this Task responseMessage,
CancellationToken token)
@@ -125,10 +132,11 @@ public static class FluentXmlTypedDeserialization
/// Awaits the response task, then reads and deserializes the XML content into the specified type
/// using the provided and .
///
- ///
- ///
- ///
- ///
+ /// The type to deserialize the XML content into.
+ /// A task that produces the HTTP response whose content will be read.
+ /// The XML reader settings to use during deserialization.
+ /// A cancellation token to observe while waiting for the task to complete.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or null if the content is empty.
public static Task ReadXmlAsync(
this Task responseMessage,
XmlReaderSettings settings,
diff --git a/src/FluentHttpClient/Guard.cs b/src/FluentHttpClient/Guard.cs
index 1fb6478..43fb581 100644
--- a/src/FluentHttpClient/Guard.cs
+++ b/src/FluentHttpClient/Guard.cs
@@ -1,5 +1,8 @@
namespace FluentHttpClient;
+///
+/// Provides internal guard clauses for parameter validation.
+///
internal static class Guard
{
public static void AgainstNull(object? value, string? paramName = null)
diff --git a/src/FluentHttpClient/HttpClientExtensions.cs b/src/FluentHttpClient/HttpClientExtensions.cs
index 8790f71..75c32cd 100644
--- a/src/FluentHttpClient/HttpClientExtensions.cs
+++ b/src/FluentHttpClient/HttpClientExtensions.cs
@@ -12,7 +12,8 @@ public static class HttpClientExtensions
/// Creates a new using the 's
/// configured as the starting point.
///
- ///
+ /// The instance to use for sending requests.
+ /// A new instance initialized with the client's base address.
public static HttpRequestBuilder UsingBase(this HttpClient client)
{
return new HttpRequestBuilder(client);
@@ -22,8 +23,9 @@ public static HttpRequestBuilder UsingBase(this HttpClient client)
/// Creates a new using the specified route
/// as the initial request URI. The value can be absolute or relative.
///
- ///
- ///
+ /// The instance to use for sending requests.
+ /// The route string for the request URI, which can be absolute or relative.
+ /// A new instance initialized with the specified route.
public static HttpRequestBuilder UsingRoute(this HttpClient client, string route)
{
return new HttpRequestBuilder(client, route);
@@ -33,8 +35,9 @@ public static HttpRequestBuilder UsingRoute(this HttpClient client, string route
/// Creates a new using the specified
/// as the initial request URI.
///
- ///
- ///
+ /// The instance to use for sending requests.
+ /// The URI for the request.
+ /// A new instance initialized with the specified URI.
public static HttpRequestBuilder UsingRoute(this HttpClient client, Uri uri)
{
return new HttpRequestBuilder(client, uri);
diff --git a/src/FluentHttpClient/HttpQueryParameterCollection.cs b/src/FluentHttpClient/HttpQueryParameterCollection.cs
index e0a2548..f262ced 100644
--- a/src/FluentHttpClient/HttpQueryParameterCollection.cs
+++ b/src/FluentHttpClient/HttpQueryParameterCollection.cs
@@ -29,7 +29,7 @@ public sealed class HttpQueryParameterCollection :
///
/// Gets the values associated with the specified key.
///
- ///
+ /// The parameter name to retrieve values for.
///
/// A read-only list of values for the key.
///
diff --git a/src/FluentHttpClient/HttpRequestBuilder.cs b/src/FluentHttpClient/HttpRequestBuilder.cs
index 30762e9..dcd4792 100644
--- a/src/FluentHttpClient/HttpRequestBuilder.cs
+++ b/src/FluentHttpClient/HttpRequestBuilder.cs
@@ -22,8 +22,8 @@ public class HttpRequestBuilder
/// Initializes a new instance of the class
/// with the specified .
///
- ///
- ///
+ /// The HTTP client to use for sending requests.
+ /// Thrown when is null.
///
/// Thrown when has a that
/// contains a query string or fragment.
@@ -46,8 +46,8 @@ internal HttpRequestBuilder(HttpClient client)
/// Initializes a new instance of the class
/// with the specified and route.
///
- ///
- ///
+ /// The HTTP client to use for sending requests.
+ /// The route string for the request.
internal HttpRequestBuilder(HttpClient client, string route)
: this(client, CreateRouteUri(route))
{
@@ -57,9 +57,9 @@ internal HttpRequestBuilder(HttpClient client, string route)
/// Initializes a new instance of the class
/// with the specified and route.
///
- ///
- ///
- ///
+ /// The HTTP client to use for sending requests.
+ /// The route URI for the request.
+ /// Thrown when is null.
///
/// Thrown when contains a query string or fragment.
///
@@ -174,7 +174,7 @@ internal HttpRequestBuilder(HttpClient client, Uri route) : this(client)
///
/// Uses and a default cancellation token.
///
- ///
+ /// The HTTP method as a string (e.g., "GET", "POST").
/// The task object representing the asynchronous operation.
///
/// Thrown when is null.
@@ -192,7 +192,7 @@ public Task SendAsync(string method)
///
/// Uses and a default cancellation token.
///
- ///
+ /// The HTTP method to use for the request.
/// The task object representing the asynchronous operation.
///
/// Thrown when is null.
@@ -210,8 +210,8 @@ public Task SendAsync(HttpMethod method)
///
/// Uses .
///
- ///
- ///
+ /// The HTTP method as a string (e.g., "GET", "POST").
+ /// A cancellation token to observe while waiting for the task to complete.
/// The task object representing the asynchronous operation.
///
/// Thrown when is null.
@@ -229,8 +229,8 @@ public Task SendAsync(string method, CancellationToken canc
///
/// Uses .
///
- ///
- ///
+ /// The HTTP method to use for the request.
+ /// A cancellation token to observe while waiting for the task to complete.
/// The task object representing the asynchronous operation.
///
/// Thrown when is null.
@@ -248,8 +248,8 @@ public Task SendAsync(HttpMethod method, CancellationToken
///
/// Uses the specified and a default cancellation token.
///
- ///
- ///
+ /// The HTTP method as a string (e.g., "GET", "POST").
+ /// Indicates when the operation should complete.
/// The task object representing the asynchronous operation.
///
/// Thrown when is null.
@@ -267,8 +267,8 @@ public Task SendAsync(string method, HttpCompletionOption c
///
/// Uses the specified and a default cancellation token.
///
- ///
- ///
+ /// The HTTP method to use for the request.
+ /// Indicates when the operation should complete.
/// The task object representing the asynchronous operation.
///
/// Thrown when is null.
@@ -283,9 +283,9 @@ public Task SendAsync(HttpMethod method, HttpCompletionOpti
///
/// Sends an HTTP request as an asynchronous operation using the configured builder state.
///
- ///
- ///
- ///
+ /// The HTTP method as a string (e.g., "GET", "POST").
+ /// Indicates when the operation should complete.
+ /// A cancellation token to observe while waiting for the task to complete.
/// The task object representing the asynchronous operation.
///
/// Thrown when is null.
@@ -306,9 +306,9 @@ public Task SendAsync(
///
/// Sends an HTTP request as an asynchronous operation using the configured builder state.
///
- ///
- ///
- ///
+ /// The HTTP method to use for the request.
+ /// Indicates when the operation should complete.
+ /// A cancellation token to observe while waiting for the task to complete.
/// The task object representing the asynchronous operation.
///
/// Thrown when is null.
@@ -333,8 +333,8 @@ public async Task SendAsync(
/// Builds and configures the for this builder instance.
/// Intended for internal and testing use. Use and its overloads to send requests.
///
- ///
- ///
+ /// The HTTP method to use for the request.
+ /// A cancellation token to observe while building the request.
/// The configured .
///
/// Thrown when is null.
@@ -412,7 +412,7 @@ internal Uri BuildRequestUri()
///
/// Applies headers, cookies, and options from the builder to the request.
///
- ///
+ /// The HTTP request message to configure.
private void ApplyConfiguration(HttpRequestMessage request)
{
if (Content is MultipartContent)
diff --git a/src/FluentHttpClient/HttpRequestBuilderExensions.cs b/src/FluentHttpClient/HttpRequestBuilderExensions.cs
index f38b5e1..9a9656c 100644
--- a/src/FluentHttpClient/HttpRequestBuilderExensions.cs
+++ b/src/FluentHttpClient/HttpRequestBuilderExensions.cs
@@ -13,6 +13,10 @@ public static class HttpRequestBuilderExtensions
/// Builds an using the current state of the builder.
/// This API is experimental and may change in future versions.
///
+ /// The instance.
+ /// The HTTP method to use for the request.
+ /// A cancellation token to observe while building the request.
+ /// A task that represents the asynchronous operation. The task result contains the built .
[Experimental("FHCBUILDREQUEST")]
public static Task BuildRequestAsync(
this HttpRequestBuilder builder,
From a2f5e92dc8cd5bfbc3b8f37a43425f75c235508f Mon Sep 17 00:00:00 2001
From: Scott Offen <3513626+scottoffen@users.noreply.github.com>
Date: Wed, 26 Nov 2025 22:33:07 -0700
Subject: [PATCH 3/8] Performance updates and documentation clarifications
---
.../FluentCookieExtensions.cs | 63 +++--
.../FluentHeaderExtensions.cs | 225 +++++++++++++-----
.../FluentJsonDeserialization.cs | 32 +++
.../FluentJsonTypedDeserialization.cs | 24 +-
.../FluentJsonTypedDeserializationAot.cs | 8 +-
.../FluentVersionExtensions.cs | 9 +-
src/FluentHttpClient/FluentXmlSerializer.cs | 13 +
.../FluentXmlTypedDeserialization.cs | 2 +-
.../HttpQueryParameterCollection.cs | 2 +-
src/FluentHttpClient/HttpRequestBuilder.cs | 79 +++++-
10 files changed, 359 insertions(+), 98 deletions(-)
diff --git a/src/FluentHttpClient/FluentCookieExtensions.cs b/src/FluentHttpClient/FluentCookieExtensions.cs
index 2bc02e6..1def38e 100644
--- a/src/FluentHttpClient/FluentCookieExtensions.cs
+++ b/src/FluentHttpClient/FluentCookieExtensions.cs
@@ -6,20 +6,41 @@ namespace FluentHttpClient;
public static class FluentCookieExtensions
{
///
- /// Adds a single cookie to the request.
+ /// Adds a single cookie to the request with optional URL encoding of the value.
///
+ ///
+ ///
+ /// By default, cookie values are URL-encoded using to ensure
+ /// special characters (such as ;, =, ,, and whitespace) do not break the
+ /// Cookie header format. This is recommended for most use cases.
+ ///
+ ///
+ /// Set to false only if the value is already properly encoded
+ /// or if you need to preserve exact byte sequences for legacy systems.
+ ///
+ ///
+ /// Existing cookies with the same name will be overwritten.
+ ///
+ ///
/// The instance.
/// The name of the cookie.
/// The value of the cookie.
+ /// If true (default), the value will be URL-encoded per RFC 6265.
+ /// Set to false to use the value as-is.
/// The for method chaining.
- public static HttpRequestBuilder WithCookie(this HttpRequestBuilder builder, string name, string value)
+ public static HttpRequestBuilder WithCookie(
+ this HttpRequestBuilder builder,
+ string name,
+ string value,
+ bool encode = true)
{
- if (string.IsNullOrWhiteSpace(name))
- {
- throw new ArgumentException("Cookie name cannot be null or empty.", nameof(name));
- }
+ Guard.AgainstNullOrEmpty(name, nameof(name));
+
+ var finalValue = encode
+ ? Uri.EscapeDataString(value ?? string.Empty)
+ : value ?? string.Empty;
- builder.Cookies[name] = value ?? string.Empty;
+ builder.Cookies[name] = finalValue;
return builder;
}
@@ -27,31 +48,37 @@ public static HttpRequestBuilder WithCookie(this HttpRequestBuilder builder, str
/// Adds multiple cookies to the request.
///
///
+ ///
+ /// By default, cookie values are URL-encoded using to ensure
+ /// special characters (such as ;, =, ,, and whitespace) do not break the
+ /// Cookie header format. This is recommended for most use cases.
+ ///
+ ///
+ /// Set to false only if the value is already properly encoded
+ /// or if you need to preserve exact byte sequences for legacy systems.
+ ///
+ ///
/// Existing cookies with the same name will be overwritten.
+ ///
///
/// The instance.
/// The collection of cookies as key-value pairs to add to the request.
+ /// If true (default), the value will be URL-encoded per RFC 6265.
+ /// Set to false to use the value as-is.
/// The for method chaining.
public static HttpRequestBuilder WithCookies(
this HttpRequestBuilder builder,
- IEnumerable> cookies)
+ IEnumerable> cookies,
+ bool encode = true)
{
- if (cookies is null)
- {
- throw new ArgumentNullException(nameof(cookies));
- }
+ Guard.AgainstNull(cookies, nameof(cookies));
foreach (var kvp in cookies)
{
var key = kvp.Key;
var value = kvp.Value;
- if (string.IsNullOrWhiteSpace(key))
- {
- throw new ArgumentException("Cookie name cannot be null or empty.", nameof(cookies));
- }
-
- builder.Cookies[key] = value ?? string.Empty;
+ builder.WithCookie(key, value, encode);
}
return builder;
diff --git a/src/FluentHttpClient/FluentHeaderExtensions.cs b/src/FluentHttpClient/FluentHeaderExtensions.cs
index 29de03e..8210677 100644
--- a/src/FluentHttpClient/FluentHeaderExtensions.cs
+++ b/src/FluentHttpClient/FluentHeaderExtensions.cs
@@ -1,3 +1,8 @@
+#if NET8_0_OR_GREATER
+using System.Collections.Frozen;
+#endif
+using System.Net.Http.Headers;
+
namespace FluentHttpClient;
///
@@ -5,21 +10,105 @@ namespace FluentHttpClient;
///
public static class FluentHeaderExtensions
{
+#if NET8_0_OR_GREATER
+ private static readonly FrozenSet _reservedHeaders =
+ FrozenSet.ToFrozenSet(
+ ["Host", "Content-Length", "Transfer-Encoding"],
+ StringComparer.OrdinalIgnoreCase);
+#else
private static readonly HashSet _reservedHeaders =
- new(StringComparer.OrdinalIgnoreCase)
+ new(StringComparer.OrdinalIgnoreCase)
+ {
+ "Host",
+ "Content-Length",
+ "Transfer-Encoding"
+ };
+#endif
+
+ ///
+ /// Configures HTTP request headers using the strongly-typed API.
+ ///
+ ///
+ ///
+ /// Use this method when you need to set headers that require strongly-typed values, such as
+ /// Authorization, CacheControl, Accept, IfModifiedSince, and other
+ /// headers with complex types or specialized formatting.
+ ///
+ ///
+ /// For simple string-based headers, use
+ /// instead, which provides better performance through direct dictionary storage.
+ ///
+ ///
+ /// Multiple calls to this method will accumulate. Each configuration action is executed when the
+ /// request is built, allowing you to compose complex header configurations.
+ ///
+ ///
+ /// The instance.
+ /// An action that configures the strongly-typed request headers.
+ /// The for method chaining.
+ ///
+ /// Setting cache control headers:
+ ///
+ /// builder.ConfigureHeaders(headers =>
+ /// {
+ /// headers.CacheControl = new CacheControlHeaderValue
+ /// {
+ /// NoCache = true,
+ /// NoStore = true,
+ /// MaxAge = TimeSpan.Zero
+ /// };
+ /// });
+ ///
+ ///
+ /// Setting multiple accept types with quality values:
+ ///
+ /// builder.ConfigureHeaders(headers =>
+ /// {
+ /// headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
+ /// headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml", 0.9));
+ /// });
+ ///
+ ///
+ /// Setting conditional request headers:
+ ///
+ /// builder.ConfigureHeaders(headers =>
+ /// {
+ /// headers.IfModifiedSince = lastModifiedDate;
+ /// headers.IfNoneMatch.Add(new EntityTagHeaderValue("\"12345\""));
+ /// });
+ ///
+ ///
+ /// Thrown when is null.
+ public static HttpRequestBuilder ConfigureHeaders(this HttpRequestBuilder builder, Action configure)
{
- "Host",
- "Content-Length",
- "Transfer-Encoding"
- };
+ Guard.AgainstNull(configure, nameof(configure));
+
+ builder.HeaderConfigurators.Add(configure);
+ return builder;
+ }
///
/// Adds the specified header and its value to the request.
///
+ ///
+ ///
+ /// If the same header name is added multiple times, all values are accumulated and sent with the request.
+ /// This is useful for headers that accept multiple values, such as Accept or Cache-Control.
+ ///
+ ///
+ /// Header names are case-insensitive per HTTP specifications.
+ ///
+ ///
+ /// Reserved headers (Host, Content-Length, Transfer-Encoding) managed by
+ /// cannot be set and will throw an immediately.
+ ///
+ ///
/// The instance.
/// The name of the header to add.
/// The value of the header.
/// The for method chaining.
+ /// Thrown when or is null.
+ /// Thrown when is a reserved header.
public static HttpRequestBuilder WithHeader(this HttpRequestBuilder builder, string key, string value)
{
Guard.AgainstNull(key, nameof(key));
@@ -33,100 +122,130 @@ public static HttpRequestBuilder WithHeader(this HttpRequestBuilder builder, str
nameof(key));
}
- builder.HeaderConfigurators.Add(target =>
- target.TryAddWithoutValidation(key, value));
+ if (builder.InternalHeaders.TryGetValue(key, out var existingValues))
+ {
+ var list = existingValues as List ?? existingValues.ToList();
+ list.Add(value);
+ builder.InternalHeaders[key] = list;
+ }
+ else
+ {
+ builder.InternalHeaders[key] = new List { value };
+ }
return builder;
}
///
- /// Adds the specified header and its values to the request.
+ /// Adds the specified header with multiple values to the request.
///
+ ///
+ ///
+ /// Each value in the collection is added to the header. If the header already exists,
+ /// the new values are appended to any existing values. This is useful for headers that
+ /// accept multiple values, such as Accept or Cache-Control.
+ ///
+ ///
+ /// This is equivalent to calling
+ /// multiple times with the same key but different values.
+ ///
+ ///
+ /// Header names are case-insensitive per HTTP specifications.
+ ///
+ ///
+ /// Reserved headers (Host, Content-Length, Transfer-Encoding) managed by
+ /// cannot be set and will throw an immediately.
+ ///
+ ///
/// The instance.
/// The name of the header to add.
/// The collection of values for the header.
/// The for method chaining.
+ /// Thrown when or is null.
+ /// Thrown when is a reserved header.
public static HttpRequestBuilder WithHeader(this HttpRequestBuilder builder, string key, IEnumerable values)
{
- Guard.AgainstNull(key, nameof(key));
Guard.AgainstNull(values, nameof(values));
- if (_reservedHeaders.Contains(key))
+ foreach (var value in values)
{
- throw new ArgumentException(
- $"Header '{key}' is managed by HttpClient/HttpContent and cannot be set using FluentHttpClient. " +
- "Configure the request URI or content instead.",
- nameof(key));
+ builder.WithHeader(key, value);
}
- builder.HeaderConfigurators.Add(target =>
- target.TryAddWithoutValidation(key, values));
-
return builder;
}
///
- /// Adds the specified headers and their values to the request.
+ /// Adds multiple headers to the request from a collection of key-value pairs.
///
+ ///
+ ///
+ /// Each header in the collection is validated and added individually. If the same header name
+ /// is provided multiple times, all values are accumulated and sent with the request.
+ /// This is useful for headers that accept multiple values, such as Accept or Cache-Control.
+ ///
+ ///
+ /// Header names are case-insensitive per HTTP specifications.
+ ///
+ ///
+ /// Reserved headers (Host, Content-Length, Transfer-Encoding) managed by
+ /// cannot be set and will throw an immediately.
+ /// If any header is invalid or reserved, an exception is thrown immediately before processing
+ /// subsequent headers.
+ ///
+ ///
/// The instance.
/// The collection of headers as key-value pairs to add to the request.
/// The for method chaining.
+ /// Thrown when is null, or when any header key or value is null.
+ /// Thrown when any header key is a reserved header.
public static HttpRequestBuilder WithHeaders(this HttpRequestBuilder builder, IEnumerable> headers)
{
Guard.AgainstNull(headers, nameof(headers));
- builder.HeaderConfigurators.Add(target =>
+ foreach (var header in headers)
{
- foreach (var header in headers)
- {
- Guard.AgainstNull(header.Key, "key");
- Guard.AgainstNull(header.Value, "value");
-
- if (_reservedHeaders.Contains(header.Key))
- {
- throw new ArgumentException(
- $"Header '{header.Key}' is managed by HttpClient/HttpContent and cannot be set using FluentHttpClient. " +
- "Configure the request URI or content instead.",
- "key");
- }
-
- target.TryAddWithoutValidation(header.Key, header.Value);
- }
- });
+ builder.WithHeader(header.Key, header.Value);
+ }
return builder;
}
///
- /// Adds the specified headers and their multiple values to the request.
+ /// Adds multiple headers with potentially multiple values per header to the request.
///
+ ///
+ ///
+ /// Each header in the collection can have multiple values. All values for a given header
+ /// are added to the request. If the same header name is provided multiple times in the collection,
+ /// all values are accumulated and sent with the request. This is useful for headers that
+ /// accept multiple values, such as Accept or Cache-Control.
+ ///
+ ///
+ /// Header names are case-insensitive per HTTP specifications.
+ ///
+ ///
+ /// Reserved headers (Host, Content-Length, Transfer-Encoding) managed by
+ /// cannot be set and will throw an immediately.
+ /// If any header is invalid or reserved, an exception is thrown immediately before processing
+ /// subsequent headers.
+ ///
+ ///
/// The instance.
/// The collection of headers where each header can have multiple values.
/// The for method chaining.
+ /// Thrown when is null, or when any header key or value collection is null.
+ /// Thrown when any header key is a reserved header.
public static HttpRequestBuilder WithHeaders(
this HttpRequestBuilder builder,
IEnumerable>> headers)
{
Guard.AgainstNull(headers, nameof(headers));
- builder.HeaderConfigurators.Add(target =>
+ foreach (var header in headers)
{
- foreach (var header in headers)
- {
- Guard.AgainstNull(header.Key, "key");
- Guard.AgainstNull(header.Value, "values");
-
- if (_reservedHeaders.Contains(header.Key))
- {
- throw new ArgumentException(
- $"Header '{header.Key}' is managed by HttpClient/HttpContent and cannot be set using FluentHttpClient. " +
- "Configure the request URI or content instead.",
- "key");
- }
-
- target.TryAddWithoutValidation(header.Key, header.Value);
- }
- });
+ builder.WithHeader(header.Key, header.Value);
+ }
return builder;
}
diff --git a/src/FluentHttpClient/FluentJsonDeserialization.cs b/src/FluentHttpClient/FluentJsonDeserialization.cs
index 7db7d60..868166d 100644
--- a/src/FluentHttpClient/FluentJsonDeserialization.cs
+++ b/src/FluentHttpClient/FluentJsonDeserialization.cs
@@ -21,6 +21,10 @@ public static class FluentJsonDeserialization
///
/// The HTTP response whose content will be read.
/// A task that represents the asynchronous operation. The task result contains the parsed JsonDocument, or null if the content is empty.
+ ///
+ /// implements and must be disposed to avoid memory leaks.
+ /// Use using statements or ensure proper disposal in asynchronous scenarios.
+ ///
public static Task ReadJsonDocumentAsync(this HttpResponseMessage response)
{
return response.ReadJsonDocumentAsync(_jsonDocumentOptions, CancellationToken.None);
@@ -33,6 +37,10 @@ public static class FluentJsonDeserialization
/// The HTTP response whose content will be read.
/// Options that control the parsing behavior.
/// A task that represents the asynchronous operation. The task result contains the parsed JsonDocument, or null if the content is empty.
+ ///
+ /// implements and must be disposed to avoid memory leaks.
+ /// Use using statements or ensure proper disposal in asynchronous scenarios.
+ ///
public static Task ReadJsonDocumentAsync(
this HttpResponseMessage response,
JsonDocumentOptions documentOptions)
@@ -47,6 +55,10 @@ public static class FluentJsonDeserialization
/// The HTTP response whose content will be read.
/// A cancellation token to observe while waiting for the task to complete.
/// A task that represents the asynchronous operation. The task result contains the parsed JsonDocument, or null if the content is empty.
+ ///
+ /// implements and must be disposed to avoid memory leaks.
+ /// Use using statements or ensure proper disposal in asynchronous scenarios.
+ ///
public static Task ReadJsonDocumentAsync(
this HttpResponseMessage response,
CancellationToken cancellationToken)
@@ -62,6 +74,10 @@ public static class FluentJsonDeserialization
/// Options that control the parsing behavior.
/// A cancellation token to observe while waiting for the task to complete.
/// A task that represents the asynchronous operation. The task result contains the parsed JsonDocument, or null if the content is empty.
+ ///
+ /// implements and must be disposed to avoid memory leaks.
+ /// Use using statements or ensure proper disposal in asynchronous scenarios.
+ ///
public static async Task ReadJsonDocumentAsync(
this HttpResponseMessage response,
JsonDocumentOptions documentOptions,
@@ -90,6 +106,10 @@ public static class FluentJsonDeserialization
///
/// A task that produces the HTTP response whose content will be read.
/// A task that represents the asynchronous operation. The task result contains the parsed JsonDocument, or null if the content is empty.
+ ///
+ /// implements and must be disposed to avoid memory leaks.
+ /// Use using statements or ensure proper disposal in asynchronous scenarios.
+ ///
public static Task ReadJsonDocumentAsync(this Task responseTask)
{
return responseTask.ReadJsonDocumentAsync(_jsonDocumentOptions, CancellationToken.None);
@@ -102,6 +122,10 @@ public static class FluentJsonDeserialization
/// A task that produces the HTTP response whose content will be read.
/// Options that control the parsing behavior.
/// A task that represents the asynchronous operation. The task result contains the parsed JsonDocument, or null if the content is empty.
+ ///
+ /// implements and must be disposed to avoid memory leaks.
+ /// Use using statements or ensure proper disposal in asynchronous scenarios.
+ ///
public static Task ReadJsonDocumentAsync(
this Task responseTask,
JsonDocumentOptions documentOptions)
@@ -116,6 +140,10 @@ public static class FluentJsonDeserialization
/// A task that produces the HTTP response whose content will be read.
/// A cancellation token to observe while waiting for the task to complete.
/// A task that represents the asynchronous operation. The task result contains the parsed JsonDocument, or null if the content is empty.
+ ///
+ /// implements and must be disposed to avoid memory leaks.
+ /// Use using statements or ensure proper disposal in asynchronous scenarios.
+ ///
public static Task ReadJsonDocumentAsync(
this Task responseTask,
CancellationToken cancellationToken)
@@ -131,6 +159,10 @@ public static class FluentJsonDeserialization
/// Options that control the parsing behavior.
/// A cancellation token to observe while waiting for the task to complete.
/// A task that represents the asynchronous operation. The task result contains the parsed JsonDocument, or null if the content is empty.
+ ///
+ /// implements and must be disposed to avoid memory leaks.
+ /// Use using statements or ensure proper disposal in asynchronous scenarios.
+ ///
public static async Task ReadJsonDocumentAsync(
this Task responseTask,
JsonDocumentOptions documentOptions,
diff --git a/src/FluentHttpClient/FluentJsonTypedDeserialization.cs b/src/FluentHttpClient/FluentJsonTypedDeserialization.cs
index 558e350..f7e48e1 100644
--- a/src/FluentHttpClient/FluentJsonTypedDeserialization.cs
+++ b/src/FluentHttpClient/FluentJsonTypedDeserialization.cs
@@ -17,9 +17,17 @@ public static partial class FluentJsonTypedDeserialization
///
/// Reads the JSON content of the response and deserializes it to .
///
+ ///
+ ///
+ /// Returns default(T?) when the response content is null or empty. For reference types, this is null.
+ /// For nullable value types (e.g., int?), this is also null. This behavior differs from
+ /// which explicitly
+ /// returns null for empty content.
+ ///
+ ///
/// The type to deserialize the JSON content into.
/// The HTTP response whose content will be read.
- /// A task that represents the asynchronous operation. The task result contains the deserialized object, or the default value if the content is empty.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or default(T?) if the content is empty.
public static Task ReadJsonAsync(this HttpResponseMessage response)
{
return response.ReadJsonAsync(
@@ -34,7 +42,7 @@ public static partial class FluentJsonTypedDeserialization
/// The type to deserialize the JSON content into.
/// The HTTP response whose content will be read.
/// Options to control the deserialization behavior.
- /// A task that represents the asynchronous operation. The task result contains the deserialized object, or the default value if the content is empty.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or default(T?) if the content is empty.
public static Task ReadJsonAsync(
this HttpResponseMessage response,
JsonSerializerOptions? options)
@@ -49,7 +57,7 @@ public static partial class FluentJsonTypedDeserialization
/// The type to deserialize the JSON content into.
/// The HTTP response whose content will be read.
/// A cancellation token to observe while waiting for the task to complete.
- /// A task that represents the asynchronous operation. The task result contains the deserialized object, or the default value if the content is empty.
+ /// A task that represents the asynchronous operation. The task result contains the deserialized object, or default(T?) if the content is empty.
public static Task ReadJsonAsync(
this HttpResponseMessage response,
CancellationToken cancellationToken)
@@ -67,7 +75,7 @@ public static partial class FluentJsonTypedDeserialization
///