Carter Library for C# (.NET): Complete Guide
1. What Is Carter and Why Use It
Carter is a lightweight, high-performance framework for building HTTP APIs on ASP.NET Core. Inspired by the popular NancyFX framework, it offers developers a familiar, declarative approach to routing and request handling. Unlike traditional MVC (Model-View-Controller), Carter lets you define endpoints directly in code without needing separate controllers or complex routing configuration.
Why use Carter? The main reason is simplicity and development speed. If you need to quickly build a minimal API or microservice, Carter provides a concise syntax that cuts down boilerplate code. It's perfect for projects that don't require the full power of MVC but still need flexibility and ease when working with requests and responses. Carter also integrates seamlessly with ASP.NET Core, leveraging its built-in dependency injection container, middleware, and other features.
Key features of Carter include: automatic binding of route parameters and request bodies (model binding), built-in validation support, straightforward error handling, and easy endpoint testing. The framework is actively maintained by the community and used in production by many companies.
2. Installation
To install Carter in your ASP.NET Core project, use the NuGet package manager. Run one of the following commands in your terminal:
dotnet add package Carter
Or via the Visual Studio Package Manager Console:
Install-Package Carter
After installation, register Carter in your Program.cs (or Startup.cs in older versions):
using Carter;
var builder = WebApplication.CreateBuilder(args);
// Add Carter to the DI container
builder.Services.AddCarter();
var app = builder.Build();
// Enable Carter middleware
app.MapCarter();
app.Run();
Note: In modern .NET versions (6+), minimal APIs are available, but Carter remains relevant for more complex logic.
3. Quick Start — Minimal Working Example
Create a new ASP.NET Core project (empty or Web API). Install Carter as described above. Then create a class implementing the ICarterModule interface:
using Carter;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
public class HomeModule : ICarterModule
{
public void AddRoutes(IEndpointRouteBuilder app)
{
// Define a GET endpoint at "/"
app.MapGet("/", () => "Hello from Carter!");
// Define a GET endpoint with a parameter
app.MapGet("/hello/{name}", (string name) => $"Hello, {name}!");
}
}
Now register this module in Program.cs:
using Carter;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCarter();
var app = builder.Build();
app.MapCarter();
app.Run();
Run the application and navigate to http://localhost:5000/hello/World. You'll see the response: Hello, World!.
4. Core Methods/Functions/Classes
Let's explore the key Carter elements you'll use most often.
4.1. ICarterModule
ICarterModule is the central interface for defining endpoint groups. Each module groups related routes together, keeping your code organized. Implement the AddRoutes method to register your endpoints.
public class ProductsModule : ICarterModule
{
public void AddRoutes(IEndpointRouteBuilder app)
{
app.MapGet("/products", () => "List of products");
app.MapGet("/products/{id}", (int id) => $"Product {id}");
app.MapPost("/products", () => "Product created");
}
}
4.2. Route Parameters and Model Binding
Carter automatically binds route parameters and request bodies to method parameters. You can use simple types like string, int, Guid, or complex objects:
app.MapPost("/users", (User user) => $"Created user: {user.Name}");
public class User
{
public string Name { get; set; }
public string Email { get; set; }
}
4.3. Response Handling
You can return various response types: strings, JSON objects, status codes, or IResult for full control:
app.MapGet("/json", () => Results.Json(new { Message = "Hello" }));
app.MapGet("/status", () => Results.StatusCode(200));
app.MapGet("/redirect", () => Results.Redirect("/new-location"));
4.4. Dependency Injection
Carter supports constructor injection in modules. Register your services in the DI container and inject them:
public class UserModule : ICarterModule
{
private readonly IUserService _userService;
public UserModule(IUserService userService)
{
_userService = userService;
}
public void AddRoutes(IEndpointRouteBuilder app)
{
app.MapGet("/users", () => _userService.GetAll());
}
}