REslava.Result.Http 1.36.0

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

REslava.Result.Http

HttpClient extensions that return Result<T> instead of throwing.

Map HTTP 4xx/5xx status codes to typed domain errors and wrap network failures in ExceptionError — no try/catch, no manual status code checks.

NuGet Downloads License

What It Does

// Before — boilerplate repeated in every service/repository
var response = await httpClient.GetAsync($"/api/users/{id}");
if (!response.IsSuccessStatusCode)
    return Result<User>.Fail(new NotFoundError("User", id));
var user = await response.Content.ReadFromJsonAsync<User>();
return Result<User>.Ok(user!);

// After
Result<User> result = await httpClient.GetResult<User>($"/api/users/{id}");
Result<Order> posted = await httpClient.PostResult<CreateOrderDto, Order>("/api/orders", dto);
Result<Order> updated = await httpClient.PutResult<UpdateOrderDto, Order>($"/api/orders/{id}", dto);
Result deleted = await httpClient.DeleteResult($"/api/orders/{id}");

Quick Start

dotnet add package REslava.Result
dotnet add package REslava.Result.Http
using REslava.Result.Http;

// In a service/repository
public async Task<Result<User>> GetUserAsync(int id, CancellationToken ct = default)
    => await _httpClient.GetResult<User>($"/api/users/{id}", cancellationToken: ct);

public async Task<Result<User>> CreateUserAsync(CreateUserDto dto, CancellationToken ct = default)
    => await _httpClient.PostResult<CreateUserDto, User>("/api/users", dto, cancellationToken: ct);

Available Methods

Method Returns
GetResult<T>(string \| Uri) Task<Result<T>>
PostResult<TBody, TResponse>(string, TBody) Task<Result<TResponse>>
PutResult<TBody, TResponse>(string, TBody) Task<Result<TResponse>>
DeleteResult(string) Task<Result>
DeleteResult<T>(string) Task<Result<T>>

All methods accept optional HttpResultOptions? and CancellationToken.

Default Error Mapping

HTTP Status Error Type Default Message
2xx ✅ Success — deserializes body
404 NotFoundError "Resource not found"
401 UnauthorizedError "Authentication required"
403 ForbiddenError "Access denied"
409 ConflictError "A conflict occurred"
422 ValidationError "Validation failed"
Other 4xx/5xx Error "HTTP {code}: {reason}"
Network exception ExceptionError Exception message

Configuration

Customise JSON deserialization and/or the status code → error mapping:

var options = new HttpResultOptions
{
    // Custom JSON options (default: JsonSerializerDefaults.Web)
    JsonOptions = new JsonSerializerOptions
    {
        PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower
    },

    // Custom status code mapper — completely replaces the built-in defaults
    StatusCodeMapper = (statusCode, reasonPhrase) => statusCode switch
    {
        HttpStatusCode.NotFound  => new NotFoundError("Order", requestedId),
        HttpStatusCode.Conflict  => new ConflictError("Order", "number", orderNumber),
        _ => new Error($"HTTP {(int)statusCode}: {reasonPhrase}")
    }
};

Result<Order> result = await httpClient.GetResult<Order>($"/api/orders/{id}", options);

Symmetry with Server Side

REslava.Result.Http completes the full round-trip with the server-side source generator:

SERVER (outbound): Result<T> → IResult → HTTP response  ← REslava.Result.SourceGenerators
CLIENT (inbound):  HTTP response → Result<T>            ← REslava.Result.Http

A server that returns Result<T> via [SmartEndpoint] can be consumed by a client that gets Result<T> back — no manual status-code inspection at either end.

Requires

MIT License | .NET 8 / 9 / 10

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 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 is compatible.  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

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.36.0 40 3/3/2026
1.35.0 82 3/2/2026
1.33.0 81 3/1/2026