Carter

repository·main·Indexed 25 days ago

https://github.com/cartercommunity/carter

A thin layer of extension methods and functionality over ASP.NET Core designed to enhance Minimal APIs. Carter provides features such as automatic validation via FluentValidation, custom content negotiation through IResponseNegotiator, easier file binding, and the ICarterModule interface for explicit route definition.

Tokens
1.2K
Snippets
6
Records
8
Agent score
32%

What's inside Carter

  1. Use custom response negotiators in Carter

    main

    Carter uses System.Text.Json by default for content negotiation. You can implement the IResponseNegotiator interface to define how responses should look based on the Accept header.

    To use a custom negotiator, register it during the Carter configuration phase:

    builder.Services.AddCarter(configurator: c =>
    {
        c.WithResponseNegotiator<CustomResponseNegotiator>();
    });

    If you prefer Newtonsoft.Json, install the Carter.ResponseNegotiators.Newtonsoft package; Carter will automatically detect and use it without manual registration.

  2. Install Carter using the dotnet template

    main

    To quickly scaffold a new project with Carter pre-configured, use the CarterTemplate.

    1. Install the template: dotnet new install CarterTemplate
    2. Create a new application: dotnet new carter -n MyCarterApp -o MyCarterApp
    3. Navigate to the directory and run: cd MyCarterApp dotnet run
    ```bash
    dotnet new install CarterTemplate
    dotnet new carter -n MyCarterApp -o MyCarterApp
    cd MyCarterApp
    dotnet run
    ```埋
  3. Install Carter as a package in an existing ASP.NET Core application

    main

    You can add Carter to an existing ASP.NET Core project manually.

    1. Create or navigate to your ASP.NET Core project.
    2. Add the Carter package: dotnet add package carter
    3. Register Carter in Program.cs using builder.Services.AddCarter() and app.MapCarter().
    4. Implement the ICarterModule interface to define your routes.
    dotnet add package carter
  4. Configure Carter via CarterConfigurator

    main

    While Carter automatically scans and registers implementations, you can use CarterConfigurator within AddCarter to manually control registration of modules, validators, and response negotiators, or to configure validator lifetimes.

    Supported configuration methods:

    • WithResponseNegotiator<T>(): Set a custom IResponseNegotiator.
    • WithModule<T>(): Manually register a module.
    • WithValidator<T>(): Manually register a validator.
    • WithDefaultValidatorLifetime(ServiceLifetime): Set the default lifetime for validators.
    • WithValidatorServiceLifetimeFactory(Func<Type, ServiceLifetime>): Provide a factory to determine lifetime based on the type.
    builder.Services.AddCarter(configurator: c =>
    {
        c.WithResponseNegotiator<CustomResponseNegotiator>();
        c.WithModule<MyModule>();
        c.WithValidator<TestModelValidator>();
        c.WithDefaultValidatorLifetime(ServiceLifetime.Singleton);
        c.WithValidatorServiceLifetimeFactory(t => {if t is PersonValidator...})
    });
  5. Validate incoming HTTP requests with FluentValidation extensions

    main

    Carter provides extensions to use FluentValidation for validating incoming HTTP requests, which is useful for Minimal APIs. You can use Validate<T> or ValidateAsync<T> on the HttpContext.

    Example usage within a module:

    private IResult HandlePost(HttpContext ctx, Person person, IDatabase database)
    {
        var result = ctx.Request.Validate(person);
    
        if (!result.IsValid)
        {
            return Results.UnprocessableEntity(result.GetFormattedErrors());
        }
    
        var id = database.StorePerson(person);
        ctx.Response.Headers.Location = $"/{id}";
        return Results.StatusCode(201);
    }
    private IResult HandlePost(HttpContext ctx, Person person, IDatabase database)
    {
        var result = ctx.Request.Validate(person);
    
        if (!result.IsValid)
        {
            return Results.UnprocessableEntity(result.GetFormattedErrors());
        }
    
        var id = database.StorePerson(person);
    
        ctx.Response.Headers.Location = $"/{id}";
        return Results.StatusCode(201);
    }
  6. Handle file uploads with Carter extensions

    main

    Carter provides several extension methods to simplify file handling in HTTP requests:

    • BindFile / BindFiles: Access one or multiple uploaded files.
    • BindFileAndSave / BindFilesAndSave: Access and automatically save uploaded files to a specified path.
  7. Implement routes using ICarterModule

    main

    To define routes in Carter, implement the ICarterModule interface. The AddRoutes method provides an IEndpointRouteBuilder where you can define your endpoints using standard ASP.NET Core Minimal API extensions.

    public class HomeModule : ICarterModule
    {
        public void AddRoutes(IEndpointRouteBuilder app)
        {
            app.MapGet("/", () => "Hello from Carter!");
        }
    }