NotoriousClient 2.0.3
See the version list below for details.
dotnet add package NotoriousClient --version 2.0.3
NuGet\Install-Package NotoriousClient -Version 2.0.3
<PackageReference Include="NotoriousClient" Version="2.0.3" />
<PackageVersion Include="NotoriousClient" Version="2.0.3" />
<PackageReference Include="NotoriousClient" />
paket add NotoriousClient --version 2.0.3
#r "nuget: NotoriousClient, 2.0.3"
#:package NotoriousClient@2.0.3
#addin nuget:?package=NotoriousClient&version=2.0.3
#tool nuget:?package=NotoriousClient&version=2.0.3
Notorious Client is meant to simplify the sending of HTTP requests through a fluent builder and an infinitely extensible client system.
Summary
- Support
- Features
- Motivation
- Getting started
- How could i use RequestBuilder ?
- How could i implement a custom BaseClient
- How could i use requestBuilder in Standalone ?
Support
- .NET 8+
Features
- Easy building of HttpRequestMessage
- Easy building of multipart/form-data requests
- Body serialisation as JSON, powered by System.Text.Json, but customisable.
- Easy handling of request's authentication
- Infinitely extensible system.
- Allow you to build maintanable and testable API Client.
Motivation
The goal is to provide a way to create API clients that is clear, fast, and above all, maintainable.
Getting Started
First, install NuGet. Then, install NotoriousClient from the package manager console:
PM> Install-Package NotoriousClient
Or from the .NET CLI as:
dotnet add package NotoriousClient
Then create a client, and inherit from BaseClient :
using NotoriousClient.Clients;
public class UserClient : BaseClient, IUserClient
{
public UserClient(IRequestSender sender, string url) : base(sender, url)
{
}
}
Add method within that client that uses RequestBuilder to build your request.
public class UserClient : BaseClient, IUserClient
{
// Define your endpoint
private Endpoint GET_USERS_ENDPOINT = new Endpoint("/api/users", Method.Get);
public UserClient(IRequestSender sender, string url) : base(sender, url)
{
}
// Add call method.
public async Task<IEnumerable<User>> GetUsers()
{
HttpRequestMessage request = GetBuilder(GET_USERS_ENDPOINT)
.WithAuthentication("username", "password")
.AddQueryParameter("limit", "100")
.Build();
HttpResponseMessage response = await Sender.SendAsync(request);
return response.ReadAs<IEnumerable<User>>();
}
}
Other example of API call.
private Endpoint GET_USER_ENDPOINT = new Endpoint("/api/users/{id}", Method.Get);
public async Task<User> GetUser(int id)
{
HttpRequestMessage request = GetBuilder(GET_USERS_ENDPOINT)
.WithAuthentication("username", "password")
.AddEndpointParameter("id", id.ToString())
.Build();
HttpResponseMessage response = await Sender.SendAsync(request);
return response.ReadAs<User>();
}
private Endpoint CREATE_USER_ENDPOINT = new Endpoint("/api/users", Method.Post);
public async Task<User> CreateUser(User user)
{
HttpRequestMessage request = GetBuilder(CREATE_USER_ENDPOINT)
.WithAuthentication("username", "password")
.WithJsonBody(user)
.Build();
HttpResponseMessage response = await Sender.SendAsync(request);
return response.ReadAs<User>();
}
Last but not least, add everything to your dependency injection.
services.AddHttpClient();
services.AddScoped<IRequestSender>((serviceProvider) => new RequestSender(serviceProvider.GetRequiredService<IHttpClientFactory>()));
services.AddScoped((serviceProvider) => new UserClient(serviceProvider.GetRequiredService<IRequestSender>(), "http://my.api.com/"));
How could i use RequestBuilder ?
Lets dive into the possibity of the RequestBuilder !
Configure URN, URL, and http verb.
new RequestBuilder("https://toto.com", "/users", Method.Get);
Configure URI parameters
Add URL parameters
new RequestBuilder("https://toto.com", "/users/{id}", Method.Get).AddEndpointParameter("id", "myfakeid");
IDictionary<string, string> endpointsParams = ...;
new RequestBuilder("https://toto.com", "/users/{id}/{name}", Method.Get).AddEndpointParameters(endpointsParams);
Add Query Parameters
new RequestBuilder("https://toto.com", "/users", Method.Get).AddQueryParameter("id", "myfakeid");
IDictionary<string, string> queryParams = ...;
new RequestBuilder("https://toto.com", "/users", Method.Get).AddQueryParameters(queryParams);
Configure request's headers
Add custom headers
new RequestBuilder("https://toto.com", "/users", Method.Get).AddCustomHeader("id", "myfakeid");
IDictionary<string, string> headers = ...;
new RequestBuilder("https://toto.com", "/users", Method.Get).AddCustomHeaders(headers);
Add accept header
new RequestBuilder("https://toto.com", "/users", Method.Get).WithCustomAcceptMediaType("application/json");
Authentication
Add basic authentication
new RequestBuilder("https://toto.com", "/users", Method.Get).WithAuthentication("login", "password");
Add bearer authentication
new RequestBuilder("https://toto.com", "/users", Method.Get).WithAuthentication("token");
Add custom scheme authentication
public class NotoriousAuthentication : IAuthenticationInformation
{
private readonly string _crownId;
private readonly string _crownName;
public NotoriousAuthentication(string crownId, string crownName)
{
_crownId = crownId;
_crownName = crownName;
}
public string Token => _crownName + _crownId;
public string Scheme => "Notorious";
}
new RequestBuilder("https://toto.com", "/users", Method.Get).WithAuthentication(new NotoriousAuthentication("1997", "BIG"));
Add body to classic request
Add body as JSON
User user = GetUsersFromDb()
new RequestBuilder("https://toto.com", "/users", Method.Get).WithJsonBody(user);
Add body as JSON with a custom serializer
public class CustomSerializer : IJsonSerializer
{
public string ConvertToJson(object obj)
{
// Your serilization logic here...
}
}
User user = GetUsersFromDb()
new RequestBuilder("https://toto.com", "/users", Method.Get).WithJsonBody(user, new CustomSerializer());
Add body as Stream
Stream stream = GetFileStream("C:/Crown/BIG.png")
new RequestBuilder("https://toto.com", "/users", Method.Get).WithStreamBody(stream);
Add body as HTTP Content
new RequestBuilder("https://toto.com", "/users", Method.Get).WithContentBody(new StringContent("MyCustomContent"));
⚠️ Note that you could use any type of content handled by .NET, such as StringContent, StreamContent, HttpContent, etc...
Add body to multipart request
⚠️ Note that you CAN'T use multipart bodies if you already added a classic body to the request
Add body as JSON
User user = GetUsersFromDb()
new RequestBuilder("https://toto.com", "/users", Method.Get).WithJsonMultipartBody(user, "USER_SECTION");
Add body as JSON with a custom serializer
public class CustomSerializer : IJsonSerializer
{
public string ConvertToJson(object obj)
{
// Your serilization logic here...
}
}
User user = GetUsersFromDb()
new RequestBuilder("https://toto.com", "/users", Method.Get).WithJsonMultipartBody(user, "USER_SECTION", new CustomSerializer());
Add body as Stream
Stream stream = GetFileStream("C:/Crown/BIG.png")
new RequestBuilder("https://toto.com", "/users", Method.Get).WithStreamMultipartBody(stream, "STREAM_SECTION");
Add body as HTTP Content
new RequestBuilder("https://toto.com", "/users", Method.Get).WithContentMultipartBody(new StringContent("MyCustomContent"), "CUSTOM_CONTENT_SECTION");
How could i implement a custom BaseClient ?
NotoriousClient is entirely designed to be infinitely extensible.
Let's say you need to get a token from an API before every request.
public class BearerAuthClient : BaseClient
{
private readonly ITokenClient _tokenClient;
public BearerAuthClient(IRequestSender sender, string url, ITokenClient tokenClient) : base(sender, url)
{
ArgumentNullException.ThrowIfNull(tokenClient, nameof(tokenClient));
_tokenClient = tokenClient;
}
protected override async Task<IRequestBuilder> GetBuilderAsync(string route, Method method = Method.Get)
{
// Get your token every time you create a request.
string token = await GetToken();
// Return a preconfigured builder with your token !
return (await base.GetBuilderAsync(route, method)).WithAuthentication(token);
}
public async Task<string> GetToken()
{
// Handle token logic here.
return await _tokenClient.GetToken();
}
}
public class UserClient : BearerAuthClient
{
private Endpoint CREATE_USER_ENDPOINT = new Endpoint("/api/users", Method.Post);
public UserClient(IRequestSender sender, string url) : base(sender, url)
{
}
public async Task<IEnumerable<User>> CreateUser(User user)
{
// Every builded request will be configured with bearer authentication !
HttpRequestMessage request = (await GetBuilderAsync(CREATE_USER_ENDPOINT))
.WithJsonBody(user)
.Build();
HttpResponseMessage response = await Sender.SendAsync(request);
return response.ReadAs<User>();
}
}
This is your turn to play with it, you could image everything you want, adding custom authentication, custom company headers, logging !
How can i use the request's builder in standalone ?
You can create a standalone builder by instantiating RequestBuilder.
// Dont forget to use IRequestBuilder to have access to extensions method !
IRequestBuilder requestBuilder = new RequestBuilder("http://my.api.com/", "api/v1.0/users", Method.GET);
Then, you will have access to all same method that you were using in Client !
| Product | Versions 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. |
-
net8.0
- Microsoft.AspNet.WebApi.Client (>= 6.0.0)
- Microsoft.Extensions.Http (>= 7.0.0)
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 |
|---|---|---|
| 2.1.0-beta.26 | 26 | 10/26/2025 |
| 2.1.0-beta.23 | 25 | 10/26/2025 |
| 2.0.3 | 215 | 9/11/2025 |
| 2.0.3-beta.20 | 123 | 9/11/2025 |
| 2.0.2 | 208 | 8/14/2025 |
| 2.0.2-beta.16 | 124 | 8/14/2025 |
| 2.0.2-beta.15 | 122 | 8/14/2025 |
| 2.0.1 | 171 | 7/7/2025 |
| 2.0.1-beta.10 | 125 | 8/14/2025 |
| 2.0.1-beta.8 | 120 | 7/7/2025 |
| 1.0.2 | 237 | 1/17/2024 |
| 1.0.1 | 202 | 9/1/2023 |
| 1.0.0 | 190 | 9/1/2023 |
| 0.0.3 | 192 | 8/30/2023 |
| 0.0.2 | 200 | 8/30/2023 |