A .NET HTTP client with an axios-like syntax.
Axios.Net targets .NET 8 and .NET 10.
dotnet add package Axios.NetOr add it to your project file:
<PackageReference Include="Axios.Net" Version="0.1.0" />using AxiosNet.Client; // Axios, AxiosClient
using AxiosNet.Config; // AxiosRequestConfig, AxiosProxy, ...
using AxiosNet.Errors; // AxiosException, CanceledError, AxiosErrorCodes
using AxiosNet.Models; // AxiosResponse<T>, AxiosHeaders, AxiosFile, AxiosProgressEvent
// Direct requests
AxiosResponse<User> res = await Axios.Get<User>("https://api.test/users/1");
Console.WriteLine($"{res.Status} {res.Data!.Name} in {res.Duration.TotalMilliseconds}ms");
await Axios.Post<User>("https://api.test/users", new { Name = "Ada" });
// Configured instance (axios.create)
AxiosClient api = Axios.Create(new()
{
BaseUrl = "https://api.test/v1",
Timeout = TimeSpan.FromSeconds(10),
Headers = { ["X-App"] = "demo" }
});
api.Defaults.CommonHeaders["Authorization"] = "Bearer token"; // axios defaults.headers.common
api.Defaults.MethodHeaders["post"] = new() { { "X-Post", "1" } }; // axios defaults.headers.post
var list = await api.Get<List<User>>("/users", new() { Params = { ["page"] = 2 } });| axios | AxiosNet |
|---|---|
axios.request(config) |
Axios.Request<T>(config) |
get / delete / head / options |
Get<T> / Delete<T> / Head<T> / Options<T>(url, config) |
post / put / patch |
Post<T> / Put<T> / Patch<T>(url, data, config) |
postForm / putForm / patchForm |
PostForm<T> / PutForm<T> / PatchForm<T> |
axios.getUri(config) |
Axios.GetUri(config) |
axios.create(config) |
Axios.Create(config, handler) |
axios.defaults / instance.defaults |
Axios.Defaults / client.Defaults |
axios.all |
Axios.All(tasks) |
axios.isAxiosError / isCancel |
Axios.IsAxiosError / IsCancel |
axios.mergeConfig |
Axios.MergeConfig |
axios.toFormData |
Axios.ToFormData |
AxiosHeaders |
AxiosHeaders |
CanceledError |
CanceledError |
Config precedence: library defaults, then client defaults, then the request config.
Url, Method and Data are never inherited from defaults; headers and params are merged key by key.
The package and assembly are named Axios.Net; the root namespace is AxiosNet so that it does not clash with the
static Axios class.
| Namespace | Types |
|---|---|
AxiosNet.Client |
Axios, AxiosClient |
AxiosNet.Config |
AxiosRequestConfig, AxiosParamsSerializer, AxiosFormSerializer, AxiosTransitional, AxiosProxy, AxiosResponseType |
AxiosNet.Errors |
AxiosException, CanceledError, AxiosErrorCodes |
AxiosNet.Models |
AxiosResponse, AxiosResponse<T>, AxiosHeaders, AxiosFile, AxiosProgressEvent |
AxiosNet.Interceptors |
AxiosInterceptors, InterceptorManager<T>, InterceptorOptions |
Url, Method, BaseUrl, AllowAbsoluteUrls, Headers, MethodHeaders / CommonHeaders, Params,
ParamsSerializer (Encode, Serialize, Indexes, MaxDepth), Data, TransformRequest,
TransformResponse, Timeout, Auth, ResponseType, ResponseEncoding, ValidateStatus,
MaxContentLength, MaxBodyLength, MaxRedirects, Decompress, Proxy, OnUploadProgress,
OnDownloadProgress, Redact, Transitional (SilentJsonParsing, ForcedJsonParsing,
ClarifyTimeoutError), FormSerializer (Dots, MetaTokens, Indexes, MaxDepth) and
CancellationToken (axios' signal).
Data:stringis sent as is (application/x-www-form-urlencodedunless a Content-Type header is set, like axios),byte[]/Streamas binary,HttpContentas is, any other object as JSON. SetContent-Type: application/x-www-form-urlencodedormultipart/form-data(or usePostForm) to serialize an object that way. UseAxiosFilefor file parts.T:string,byte[]andStreamreturn the raw body; anything else is read as JSON (System.Text.Json, web defaults). Override withResponseType.- Query arrays follow axios:
a[]=1&a[]=2by default; useIndexes = nullfora=1&a=2ortruefora[0]=1. - Responses expose
Status,StatusText,Headers(lowercase names),Config,Request,DurationandData.
Every failure throws an AxiosException (Code, Config, Request, Response, Status, ToJSON()).
Codes are in AxiosErrorCodes: ERR_BAD_REQUEST (4xx), ERR_BAD_RESPONSE, ERR_NETWORK, ERR_CANCELED
(CanceledError), ERR_INVALID_URL, ERR_FORM_DATA_DEPTH_EXCEEDED, ECONNABORTED / ETIMEDOUT (timeouts).
Use ValidateStatus to resolve selected status codes, and Redact to mask keys in ToJSON().
try { await api.Get<User>("/missing"); }
catch (AxiosException e) { Console.WriteLine($"{e.Code} {e.Status} {e.Response?.Data}"); }int id = api.Interceptors.Request.Use(
config => { config.Headers["X-Trace"] = Guid.NewGuid().ToString(); return config; },
options: new() { RunWhen = c => c.Method == HttpMethod.Get, Synchronous = true });
api.Interceptors.Response.Use(
response => response,
error => error is AxiosException { Response: { } r } ? r : throw error); // recover or rethrow
api.Interceptors.Request.Eject(id);
api.Interceptors.Response.Clear();Request interceptors run last registered first, response interceptors first registered first.
dotnet add package Axios.Net.Extensions.DependencyInjectionusing AxiosNet.Extensions.DependencyInjection;
services.AddAxios(c => c.BaseUrl = "https://api.test/v1/");AxiosClient is registered as a singleton, so inject it where you need it:
public class UserService(AxiosClient api)
{
public Task<AxiosResponse<User>> Get(int id) => api.Get<User>($"/users/{id}");
}The client sends its requests through an IHttpClientFactory named client called Axios.Net. Chain on it to add handlers, such as logging or resilience:
services.AddHttpClient("Axios.Net")
.AddHttpMessageHandler<MyLoggingHandler>();Because the handler comes from the factory, MaxRedirects, Decompress and Proxy are no longer read from the request config. Configure them on the primary handler instead (ConfigurePrimaryHttpMessageHandler).
The singleton keeps the handler it was created with, so it is not recycled and DNS changes are not picked up for the lifetime of the app.
These axios options are tied to browsers or Node.js and have no equivalent: adapter (pass an
HttpMessageHandler to Axios.Create instead), xsrfCookieName, xsrfHeaderName, withXSRFToken,
withCredentials, httpAgent, httpsAgent, socketPath, allowedSocketPaths, transport,
insecureHTTPParser, formDataHeaderPolicy, env, maxRate, beforeRedirect, sensitiveHeaders,
parseReviver (configure AxiosClient.JsonOptions), and the deprecated CancelToken (use CancellationToken).
MaxRedirects, Decompress and Proxy need the built-in handler (they are ignored with a custom one).
Copyright (C) 2026 Frenchy Apps 42
Axios.Net is free software: you can redistribute it and/or modify it under the terms of the
GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the
License,
or (at your option) any later version (AGPL-3.0-or-later).
Axios.Net is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. See the LICENSE file for the full terms.
In short: you can use, study, change and share it freely. If you distribute a modified version, or let other people use a modified version over a network, you must offer them its source code under the same license.