Linger.HttpClient.Contracts
2.0.0-preview.1
dotnet add package Linger.HttpClient.Contracts --version 2.0.0-preview.1
NuGet\Install-Package Linger.HttpClient.Contracts -Version 2.0.0-preview.1
<PackageReference Include="Linger.HttpClient.Contracts" Version="2.0.0-preview.1" />
<PackageVersion Include="Linger.HttpClient.Contracts" Version="2.0.0-preview.1" />
<PackageReference Include="Linger.HttpClient.Contracts" />
paket add Linger.HttpClient.Contracts --version 2.0.0-preview.1
#r "nuget: Linger.HttpClient.Contracts, 2.0.0-preview.1"
#:package Linger.HttpClient.Contracts@2.0.0-preview.1
#addin nuget:?package=Linger.HttpClient.Contracts&version=2.0.0-preview.1&prerelease
#tool nuget:?package=Linger.HttpClient.Contracts&version=2.0.0-preview.1&prerelease
Linger.HttpClient.Contracts
Interfaces and transport models for Linger.HttpClient. This package contains no HTTP request implementation.
Included APIs
IHttpClient: typed calls, raw responses, streaming file uploads, and file downloadsApiResult/ApiResult<T>: transport results with HTTP status and structured errorsProblemDetailsWithErrors: RFC 7807 field-error modelHttpClientExtensions: GET, POST, PUT, and DELETE convenience methods
The implementation is provided by Linger.HttpClient.Standard.
Installation
dotnet add package Linger.HttpClient.Contracts
dotnet add package Linger.HttpClient.Standard
Core interface
public interface IHttpClient
{
Task<HttpResponseMessage> SendAsync(
string url,
HttpMethod method,
object? requestBody = null,
object? queryParams = null,
IReadOnlyDictionary<string, string>? headers = null,
HttpCompletionOption completionOption = HttpCompletionOption.ResponseHeadersRead,
CancellationToken cancellationToken = default);
Task<ApiResult<T>> CallApi<T>(
string url,
HttpMethod method,
object? requestBody = null,
object? queryParams = null,
IReadOnlyDictionary<string, string>? headers = null,
CancellationToken cancellationToken = default);
Task<ApiResult<T>> UploadFileAsync<T>(
string url,
HttpMethod method,
Stream fileStream,
string fileName,
IReadOnlyDictionary<string, string>? formData = null,
string fileFieldName = "file",
string? contentType = null,
IReadOnlyDictionary<string, string>? headers = null,
CancellationToken cancellationToken = default);
Task<ApiResult> DownloadToFileAsync(
string url,
string destinationPath,
int bufferSize = 8192,
IProgress<(long downloaded, long? total)>? progress = null,
IReadOnlyDictionary<string, string>? headers = null,
CancellationToken cancellationToken = default);
}
Basic usage
services.AddHttpClient<IHttpClient, StandardHttpClient>(client =>
{
client.BaseAddress = new Uri("https://api.example.com/");
client.Timeout = TimeSpan.FromSeconds(30);
});
var result = await httpClient.GetAsync<User>(
"users/42",
headers: new Dictionary<string, string>
{
["Authorization"] = $"Bearer {accessToken}"
},
cancellationToken: cancellationToken);
Use GetWithTimeoutAsync when one GET request needs a timeout different from the client default:
var result = await httpClient.GetWithTimeoutAsync<User>(
"users/42",
timeout: TimeSpan.FromSeconds(5),
cancellationToken: cancellationToken);
A one-off timeout returns a failed ApiResult<T>; caller cancellation through cancellationToken still throws OperationCanceledException. Passing null or Timeout.InfiniteTimeSpan adds no per-request timeout.
Dynamic headers apply only to one request. The client stores no mutable shared token/header state and does not append a culture query parameter. Configure fixed headers through AddHttpClient; a caller-owned dedicated HttpClient, such as in WinForms, can instead set DefaultRequestHeaders.Authorization when the instance is created. Continue using per-request headers when one client can represent different users. The contracts package does not store or refresh tokens; see the Linger.HttpClient.Standard README for complete DelegatingHandler integration with Linger.AspNetCore.Jwt refresh tokens.
Request bodies
CallApi<T> creates content according to requestBody:
HttpContent: sent directly and disposed when the request completesIDictionary<string, string>: sent asapplication/x-www-form-urlencoded- Other objects: serialized as JSON
var result = await httpClient.CallApi<User>(
"users",
HttpMethod.Post,
new CreateUserRequest("Ada"),
cancellationToken: cancellationToken);
Raw responses and streaming
Use SendAsync when you need response headers, SSE, or incremental content processing. The request still uses the same base address, default headers, and DelegatingHandler pipeline:
using var response = await httpClient.SendAsync(
"events",
HttpMethod.Get,
cancellationToken: cancellationToken);
response.EnsureSuccessStatusCode();
using var stream = await response.Content.ReadAsStreamAsync();
await ProcessStreamAsync(stream, cancellationToken);
The caller must dispose the returned HttpResponseMessage. SendAsync does not parse unsuccessful responses or convert transport exceptions into ApiResult; use CallApi<T> when the unified error model is required.
File transfers
Uploads use StreamContent and do not copy the complete file into a byte[]. The input stream is disposed when the upload request completes.
var stream = File.OpenRead("report.pdf");
var upload = await httpClient.UploadFileAsync<FileInfoDto>(
"files",
HttpMethod.Post,
stream,
"report.pdf",
cancellationToken: cancellationToken);
Downloads stream into a same-directory temporary file and replace the destination only after a successful flush. Cancellation or transfer failure removes the temporary file and preserves an existing destination.
var download = await httpClient.DownloadToFileAsync(
"files/report.pdf",
"report.pdf",
progress: progress,
cancellationToken: cancellationToken);
Errors and cancellation
IsSuccessistrueonly for a 2xx response without parsing errors- ProblemDetails
errorsentries are flattened intoApiResult.Errors - Legacy
IEnumerable<Error>JSON arrays remain supported as a compatibility fallback - Network, timeout, and JSON errors from typed calls return a failed
ApiResult - User cancellation always throws
OperationCanceledException
Raw HttpResponseMessage and response streams are not returned through generic T; they are exposed through the ownership-explicit SendAsync method.
| 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 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 is compatible. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.7.2
- No dependencies.
-
.NETStandard 2.0
- No dependencies.
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Linger.HttpClient.Contracts:
| Package | Downloads |
|---|---|
|
Linger.HttpClient.Standard
A lightweight implementation of Linger.HttpClient.Contracts using standard .NET HttpClient. Provides typed response parsing, per-request headers, and streaming file transfers. Seamlessly integrates with .NET's HttpClientFactory for optimal connection management. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.0-preview.1 | 34 | 8/29/2026 |
| 1.6.4 | 140 | 8/16/2026 |
| 1.6.3 | 131 | 8/5/2026 |
| 1.6.2 | 159 | 8/2/2026 |
| 1.6.0 | 148 | 7/25/2026 |
| 1.5.5 | 147 | 7/23/2026 |
| 1.5.4-preview | 116 | 7/21/2026 |
| 1.5.3-preview | 125 | 7/20/2026 |
| 1.5.2-preview | 144 | 7/19/2026 |
| 1.5.1-preview | 125 | 7/15/2026 |
| 1.5.0-preview | 131 | 7/14/2026 |
| 1.4.4-preview | 145 | 6/16/2026 |
| 1.4.3-preview | 141 | 6/15/2026 |
| 1.4.2 | 174 | 5/20/2026 |
| 1.4.1-preview | 146 | 5/12/2026 |
| 1.4.0 | 162 | 5/6/2026 |
| 1.3.3-preview | 131 | 5/5/2026 |
| 1.3.2-preview | 135 | 4/29/2026 |
| 1.3.1-preview | 145 | 4/28/2026 |
| 1.3.0-preview | 143 | 4/27/2026 |