DSeries.DHttpClient.Core
1.0.6
dotnet add package DSeries.DHttpClient.Core --version 1.0.6
NuGet\Install-Package DSeries.DHttpClient.Core -Version 1.0.6
<PackageReference Include="DSeries.DHttpClient.Core" Version="1.0.6" />
<PackageVersion Include="DSeries.DHttpClient.Core" Version="1.0.6" />
<PackageReference Include="DSeries.DHttpClient.Core" />
paket add DSeries.DHttpClient.Core --version 1.0.6
#r "nuget: DSeries.DHttpClient.Core, 1.0.6"
#:package DSeries.DHttpClient.Core@1.0.6
#addin nuget:?package=DSeries.DHttpClient.Core&version=1.0.6
#tool nuget:?package=DSeries.DHttpClient.Core&version=1.0.6
DHttpClient - A Fluent HTTP Request Builder for .NET
DHttpClient is a flexible and fluent HTTP request builder for .NET applications. It simplifies making HTTP requests by providing an intuitive API for configuring requests, handling responses, and managing various content types.
Features
- Fluent API: Chainable, readable syntax.
- All HTTP Methods: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS.
- Flexible Content Handling
- JSON serialization & deserialization
- Form URL‑encoded content
- Multipart form‑data for file uploads
- Automatic Query Parameter Handling
- Custom Headers at both request and content levels
- Per‑request CancellationToken Support (for timeouts/cancellation)
- Unified Error Handling with
Result<T>
wrapper - Dependency‑Injection Ready via
IHttpClientFactory
- Stream & Byte‑Array Support for downloads
- Live Stream Support (e.g., Server‑Sent Events)
Installation
Add the NuGet package to your .NET project:
Install-Package DHttpClient
# or
dotnet add package DHttpClient
## Usage
### Basic GET Request
```csharp
var client = new DHttpClient(new HttpClient(), disposeHttpClient: false)
.WithRequestUri("https://httpbin.org/get")
.WithMethod(HttpMethod.Get);
var result = await client.SendAsync();
if (result.IsSuccess)
Console.WriteLine($"Status: {result.Data.StatusCode}");
else
Console.WriteLine($"Error: {result.ErrorMessage}");
GET Request with Query Parameters
var request = new DHttpClient(new HttpClient(), disposeHttpClient: false)
.WithRequestUri("https://httpbin.org/get")
.WithQueryParameters(new { user = "JohnDoe", age = 30 })
.WithMethod(HttpMethod.Get);
POST Request with JSON Payload
var payload = new { name = "John", email = "john@example.com" };
var request = new DHttpClient(new HttpClient(), disposeHttpClient: false)
.WithRequestUri("https://httpbin.org/post")
.WithMethod(HttpMethod.Post)
.WithBodyContent(payload);
POST Request with Form URL-Encoded Content
var formData = new Dictionary<string, string>
{
{ "username", "testuser" },
{ "password", "securepassword" }
};
var request = new DHttpClient(new HttpClient(), disposeHttpClient: false)
.WithRequestUri("https://httpbin.org/post")
.WithMethod(HttpMethod.Post)
.WithFormUrlEncodedContent(formData);
Multipart Form-Data (File Upload)
var multipartRequest = new DHttpClient(new HttpClient(), disposeHttpClient: false)
.WithRequestUri("https://httpbin.org/post")
.WithMethod(HttpMethod.Post)
.WithFormMultiPartContent(builder => builder
.AddTextContent("description", "Test file upload")
.AddFileContent("file", File.ReadAllBytes("test.txt"), "test.txt"));
Handling JSON Responses
var request = new DHttpClient(new HttpClient(), disposeHttpClient: false)
.WithRequestUri("https://httpbin.org/json")
.WithMethod(HttpMethod.Get);
var response = await request.SendObjectAsync<MyResponseModel>();
if (response.IsSuccess)
{
Console.WriteLine(response.Data.SomeProperty);
}
Configuring Headers
var request = new DHttpClient(new HttpClient(), disposeHttpClient: false)
.WithRequestUri("https://httpbin.org/get")
.WithMethod(HttpMethod.Get)
.WithHeader("Authorization", "Bearer YOUR_TOKEN")
.WithHeader("Custom-Header", "HeaderValue");
Setting Custom Timeout
var request = new DHttpClient(new HttpClient(), disposeHttpClient: false)
.WithRequestUri("https://httpbin.org/get")
.WithMethod(HttpMethod.Get)
.WithTimeout(TimeSpan.FromSeconds(10));
Using a Custom HttpClient
var httpClient = new HttpClient();
var request = new HttpRequestBuilder(httpClient)
.WithRequestUri("https://httpbin.org/get")
.WithMethod(HttpMethod.Get);
Handling Multipart Requests
var request = new DHttpClient(new HttpClient(), disposeHttpClient: false)
.WithRequestUri("https://httpbin.org/post")
.WithMethod(HttpMethod.Post)
.WithFormMultiPartContent(builder => builder
.AddTextContent("key", "value")
.AddFileContent("file", File.ReadAllBytes("image.png"), "image.png"));
DHttpClient - Send Functionalities Overview
Sending Requests in DHttpClient
DHttpClient provides multiple methods for sending HTTP requests and handling responses in a structured way using the Result<T>
wrapper.
SendAsync()
Description:
Sends the HTTP request asynchronously and returns the raw HttpResponseMessage
wrapped in a Result<HttpResponseMessage>
.
Usage:
var request = new DHttpClient(new HttpClient(), disposeHttpClient: false)
.WithRequestUri("https://httpbin.org/get")
.WithMethod(HttpMethod.Get);
var result = await request.SendAsync();
if (result.IsSuccess)
{
Console.WriteLine($"Response Status: {result.Data.StatusCode}");
}
else
{
Console.WriteLine($"Error: {result.ErrorMessage}");
}
SendStringAsync()
Description:
Sends the HTTP request and returns the response body as a string
, wrapped in a Result<string>
.
Usage:
var result = await request.SendStringAsync();
if (result.IsSuccess)
{
Console.WriteLine(result.Data); // The raw response content
}
else
{
Console.WriteLine($"Error: {result.ErrorMessage}");
}
SendObjectAsync<T>()
Description:
Sends the HTTP request and deserializes the JSON response to an object of type T
, wrapped in a Result<T>
.
Usage:
public class ApiResponse
{
public string Message { get; set; }
}
var result = await request.SendObjectAsync<ApiResponse>();
if (result.IsSuccess)
{
Console.WriteLine(result.Data.Message); // Access the deserialized object
}
else
{
Console.WriteLine($"Error: {result.ErrorMessage}");
}
SendStreamAsync()
Description:
Sends the request and returns the response content as a Stream
, wrapped in a Result<Stream>
. Useful for downloading large files.
Usage:
var result = await request.SendStreamAsync();
if (result.IsSuccess)
{
using var fileStream = File.Create("downloadedFile.txt");
await result.Data.CopyToAsync(fileStream);
Console.WriteLine("File downloaded successfully.");
}
else
{
Console.WriteLine($"Error: {result.ErrorMessage}");
}
SendBytesAsync()
Description:
Sends the request and returns the response content as a byte[]
, wrapped in a Result<byte[]>
. Useful for handling binary data.
Usage:
var result = await request.SendBytesAsync();
if (result.IsSuccess)
{
File.WriteAllBytes("image.png", result.Data);
Console.WriteLine("Image downloaded successfully.");
}
else
{
Console.WriteLine($"Error: {result.ErrorMessage}");
}
Error Handling
Each method returns a Result<T>
that includes:
IsSuccess
: Indicates if the request was successful.Data
: The response content in the respective format (HttpResponseMessage
,string
,T
,Stream
,byte[]
).ErrorMessage
: Contains error details if the request fails.StatusCode
: The HTTP status code of the response (if available).
Example:
var response = await request.SendStringAsync();
if (!response.IsSuccess)
{
Console.WriteLine($"Error: {response.ErrorMessage}");
}
SendLiveStreamAsync()
Description:
Sends the request expecting a text-based, line-delimited stream (like Server-Sent Events, SSE). Returns a Result<IAsyncEnumerable<string>>
. You must first check Result.IsSuccess
to ensure the stream connection was successfully established before attempting to iterate the stream using await foreach
. The method handles proper resource disposal (ensuring the HttpResponseMessage
and stream are cleaned up).
Usage:
using System.Collections.Generic; // For IAsyncEnumerable
using System.Runtime.CompilerServices; // For [EnumeratorCancellation]
using System.Threading;
using System.Threading.Tasks;
using DHttpClient.Models; // For Result<T>
using System; // For Exception
// Requires System.Linq.Async NuGet package for the WithCancellation extension if desired
// Assuming a builder is configured for a live stream endpoint...
var streamBuilder = new DHttpClient(new HttpClient(), disposeHttpClient: false)
.WithRequestUri("https://your-sse-endpoint.com/stream") // Replace with your stream URL
.WithMethod(HttpMethod.Get); // SSE is typically GET
// Use a CancellationToken source for manual cancellation or timeout
// For timeout, use: using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(5));
using var cts = new CancellationTokenSource();
CancellationToken cancellationToken = cts.Token;
try
{
// Attempt to establish the stream connection
Result<IAsyncEnumerable<string>> liveStreamResult = await streamBuilder.SendLiveStreamAsync(cancellationToken: cancellationToken);
if (liveStreamResult.IsSuccess)
{
Console.WriteLine("Successfully connected to live stream. Reading data...");
// If successful, iterate over the stream using await foreach
// .WithCancellation(cancellationToken) is highly recommended if using a CancellationToken
await foreach (string line in liveStreamResult.Data.WithCancellation(cancellationToken))
{
// Process each received line (the 'data:' prefix is already removed)
Console.WriteLine($"Received: {line}");
// Example: Stop reading based on content
if (line == "END_STREAM")
{
cts.Cancel(); // Request cancellation of the await foreach loop
Console.WriteLine("Received END_STREAM, requesting cancellation.");
}
}
// The await foreach loop exits when the server closes the stream,
// an error occurs, or the CancellationToken is triggered.
Console.WriteLine("Stream iteration finished.");
// Resources (HttpResponseMessage, Stream, Reader) are automatically disposed
// because the IAsyncEnumerable completed or was cancelled.
}
else
{
// Handle failure to establish the stream connection (e.g., 404, 500, network error)
Console.WriteLine($"Error establishing stream: {liveStreamResult.ErrorMessage}");
// Check liveStreamResult.StatusCode for the HTTP status code if available
if (liveStreamResult.StatusCode.HasValue)
{
Console.WriteLine($"HTTP Status: {liveStreamResult.StatusCode.Value}");
}
}
}
catch (OperationCanceledException)
{
// This catch block handles cancellation explicitly triggered via the CancellationToken
Console.WriteLine("Live stream operation was explicitly cancelled (e.g., via CancellationToken).");
}
catch (Exception ex)
{
// This catch block handles unexpected errors that might occur *during* stream reading
// (e.g., connection dropped mid-stream).
Console.WriteLine($"An unexpected error occurred during stream reading: {ex.Message}");
}
These send functionalities provide **structured error handling** and **typed responses**, making HTTP operations in .NET applications more robust and reliable. 🚀
---
## License
This project is licensed under the MIT License.
---
## Contributing
Contributions are welcome! Please open an issue or submit a pull request if you have improvements.
---
## Contact
For questions or issues, open an issue on GitHub.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.1 is compatible. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- Microsoft.Extensions.Http (>= 9.0.2)
- Newtonsoft.Json (>= 13.0.3)
- System.Text.Json (>= 9.0.4)
-
net8.0
- Microsoft.Extensions.Http (>= 9.0.2)
- Newtonsoft.Json (>= 13.0.3)
- System.Text.Json (>= 9.0.4)
-
net9.0
- Microsoft.Extensions.Http (>= 9.0.2)
- Newtonsoft.Json (>= 13.0.3)
- System.Text.Json (>= 9.0.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
# Release Notes – DHttpClient v1.0.6
## 🚀 Features
- **Fluent API Design**
- Chainable methods for building HTTP requests with improved readability and clarity.
- **HTTP Methods Support**
- All major HTTP verbs supported: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS.
- **Content Type Support**
- JSON payloads (object & dictionary)
- Form URL-encoded content
- Multipart form-data (for file uploads)
- Raw HttpContent
- **Response Handling**
- Send as: HttpResponseMessage, string, object (with deserialization), Stream, byte array
- Live stream support via `IAsyncEnumerable<string>`
- **Error Handling**
- Unified `Result<T>` wrapper for consistent success/error reporting
- Built-in error messages and status code capture
- **Custom Headers**
- Per-request headers and content-level headers support
- **Cancellation Support**
- Use `CancellationToken` for per-request timeout and cancellation control
- **Serialization Extensions**
- Object to JSON and JSON to object using System.Text.Json with camelCase support
- URL-encoding helpers for query strings and form data
- **Streaming Support**
- Stream responses (`SendStreamAsync`)
- Live line-delimited streaming (`SendLiveStreamAsync`)
- **DI Integration**
- Register with ASP.NET Core's `IHttpClientFactory` via `AddDHttpClient()` extension methods
## 🛠 Improvements
- Helper classes like `MultiPartContentBuilder` to simplify complex payloads
- Strongly typed extension methods for form, query, and base64 operations
- Proper disposal of response resources and error resilience
## ✅ Compatibility
- .NET Standard 2.1+, .NET 6+, .NET 7, .NET 8
- Built for modern .NET projects using System.Text.Json and IHttpClientFactory
## 📦 Installation
```bash
Install-Package DHttpClient
# or
dotnet add package DHttpClient