SergeiM.Http 0.5.0

dotnet add package SergeiM.Http --version 0.5.0
                    
NuGet\Install-Package SergeiM.Http -Version 0.5.0
                    
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="SergeiM.Http" Version="0.5.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SergeiM.Http" Version="0.5.0" />
                    
Directory.Packages.props
<PackageReference Include="SergeiM.Http" />
                    
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 SergeiM.Http --version 0.5.0
                    
#r "nuget: SergeiM.Http, 0.5.0"
                    
#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 SergeiM.Http@0.5.0
                    
#: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=SergeiM.Http&version=0.5.0
                    
Install as a Cake Addin
#tool nuget:?package=SergeiM.Http&version=0.5.0
                    
Install as a Cake Tool

SergeiM.Http

GitHub Actions Workflow Status NuGet Version Hits-of-Code GitHub License

A fluent HTTP client library for .NET that provides a pure OOP approach to building and executing HTTP requests with method chaining.

Installation

dotnet add package SergeiM.Http

Quick Start

Simple GET Request

var response = new Request("https://api.example.com")
    .Uri().Path("/users").QueryParam("id", 123).Back()
    .Method(Request.GET)
    .Fetch();

JSON Response

var response = new Request("https://api.example.com")
    .Uri().Path("/users").QueryParam("id", 123).Back()
    .Header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON)
    .Fetch()
    .As<JsonResponse>()
    .AssertStatus(200);

var user = response.AsObject();
string userName = user.GetString("name");
int age = user.GetInt("age");
bool isActive = user.GetBoolean("is_active", false);

XML Response with XPath

string href = new Request("https://api.example.com")
    .Uri().Path("/data").Back()
    .Header(HttpHeaders.ACCEPT, MediaType.TEXT_XML)
    .Fetch()
    .As<XmlResponse>()
    .AssertStatus(200)
    .AssertXPath("/page/links/link[@rel='see']")
    .EvaluateXPath("/page/links/link[@rel='see']/@href");

Complex Chaining Example

string name = new Request("https://www.example.com:8080")
    .Uri().Path("/users").QueryParam("id", 333).Back()
    .Method(Request.GET)
    .Header(HttpHeaders.ACCEPT, MediaType.TEXT_XML)
    .Fetch()
    .As<RestResponse>()
    .AssertStatus(200)
    .As<XmlResponse>()
    .AssertXPath("/page/links/link[@rel='see']")
    .Rel("/page/links/link[@rel='see']/@href")
    .Header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON)
    .Fetch()

Wire System

SergeiM.Http uses a wire system for sending HTTP requests, allowing you to customize and extend request handling through decorators.

Basic Wire Usage

By default, requests use HttpWire:

var response = new Request("https://api.example.com").Fetch();

Custom Wire

You can specify a custom wire implementation:

var response = new Request("https://api.example.com", new HttpWire()).Fetch();

Changing Wire with Through()

Change the wire at any point using the Through() method:

var response = new Request("https://api.example.com")
    .Through(new HttpWire())
    .Fetch();

Authorization Wire

Add authorization headers to requests:

var response = new Request("https://api.example.com")
    .Through(new BasicAuthWire(new HttpWire(), "Bearer your-token"))
    .Fetch();

Retry Wire

Add automatic retry logic for failed requests:

var response = new Request("https://api.example.com", new RetryWire(
    new HttpWire(),
    maxRetries: 5,
    delayBetweenRetries: TimeSpan.FromSeconds(2)
)).Fetch();

Chaining Wire Decorators

Combine multiple decorators for advanced functionality:

var wire = new RetryWire(
    new BasicAuthWire(
        new HttpWire(),
        "Bearer token"
    ),
    maxRetries: 3,
    delayBetweenRetries: TimeSpan.FromSeconds(1)
);
var response = new Request("https://api.example.com", wire)
    .Uri().Path("/data").Back()
    .Fetch();

Or fluently with Through():

var response = new Request("https://api.example.com")
    .Through(new BasicAuthWire(new HttpWire(), "Bearer token"))
    .Uri().Path("/protected-resource").Back()
    .Through(new RetryWire(
        new BasicAuthWire(new HttpWire(), "Bearer token"),
        3,
        TimeSpan.FromSeconds(2)
    ))
    .Fetch();

Custom Wire Implementation

Create your own wire by implementing IWire:

public class LoggingWire : IWire
{
    private readonly IWire _origin;
    private readonly ILogger _logger;

    public LoggingWire(IWire origin, ILogger logger)
    {
        _origin_ = origin;
        _logger = logger;
    }

    public async Task<HttpResponseMessage> SendAsync(
        string method,
        string uri,
        Dictionary<string, string> headers,
        string? body = null)
    {
        _logger.Log($"Sending {method} request to {uri}");
        var response = await _innerWire.SendAsync(method, uri, headers, body);
        _logger.Log($"Received {response.StatusCode} from {uri}");
        return response;
    }

    public HttpResponseMessage Send(
        string method,
        string uri,
        Dictionary<string, string> headers,
        string? body = null)
    {
        return SendAsync(method, uri, headers, body).GetAwaiter().GetResult();
    }
}

Building

dotnet build

Testing

dotnet test

Conventional Commits

This project follows Conventional Commits to automate versioning and changelog generation via release-please.

Type Purpose Bump
feat New feature minor
fix Bug fix patch
docs Documentation only changes
style Code style (formatting, whitespace)
refactor Code refactoring
test Adding or updating tests
chore Maintenance (CI, deps, etc.)

Breaking changes are signaled with ! after the type (feat!:) or a BREAKING CHANGE: footer — triggers a major bump.

License

See LICENSE.txt for details.

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

NuGet packages (1)

Showing the top 1 NuGet packages that depend on SergeiM.Http:

Package Downloads
SergeiM.Soap

Immutable fluent SOAP 1.1 and SOAP 1.2 client for .NET 8, built on SergeiM.Http. Send SOAP requests, parse envelopes and faults, and assert responses with a chainable API.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.5.0 0 6/24/2026
0.4.1 140 2/25/2026
0.4.0 125 2/4/2026
0.3.0 113 2/3/2026
0.2.0 124 1/15/2026
0.1.1 118 12/28/2025
0.1.0 166 12/20/2025
0.0.1 174 12/14/2025