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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="DSeries.DHttpClient.Core" Version="1.0.6" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DSeries.DHttpClient.Core" Version="1.0.6" />
                    
Directory.Packages.props
<PackageReference Include="DSeries.DHttpClient.Core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add DSeries.DHttpClient.Core --version 1.0.6
                    
#r "nuget: DSeries.DHttpClient.Core, 1.0.6"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package DSeries.DHttpClient.Core@1.0.6
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=DSeries.DHttpClient.Core&version=1.0.6
                    
Install as a Cake Addin
#tool nuget:?package=DSeries.DHttpClient.Core&version=1.0.6
                    
Install as a Cake Tool

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.6 183 4/22/2025
1.0.5 178 4/22/2025
1.0.4 132 4/18/2025
1.0.3 138 3/16/2025

# 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