CarpaNet.AspNetCore 1.0.1

dotnet add package CarpaNet.AspNetCore --version 1.0.1
                    
NuGet\Install-Package CarpaNet.AspNetCore -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CarpaNet.AspNetCore" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CarpaNet.AspNetCore" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="CarpaNet.AspNetCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CarpaNet.AspNetCore --version 1.0.1
                    
#r "nuget: CarpaNet.AspNetCore, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CarpaNet.AspNetCore@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CarpaNet.AspNetCore&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=CarpaNet.AspNetCore&version=1.0.1
                    
Install as a Cake Tool

CarpaNet.AspNetCore

NuGet Version License

ASP.NET Core XRPC server endpoint support for CarpaNet. Generate abstract ATProtocol XRPC controllers from lexicon definitions and implement your own ATProtocol server endpoints.

Installation

dotnet add package CarpaNet.AspNetCore

You also need the core CarpaNet package (with source generator) to generate the controllers and data model types.

Quick Start

1. Enable XRPC endpoint generation

Set CarpaNet_EmitXrpcEndpoints to true in your ASP.NET Core project:

<PropertyGroup>
  <CarpaNet_EmitXrpcEndpoints>true</CarpaNet_EmitXrpcEndpoints>
  <CarpaNet_LexiconAutoResolve>true</CarpaNet_LexiconAutoResolve>
</PropertyGroup>

<ItemGroup>
  <LexiconResolve Include="com.atproto.server.describeServer" />
  <LexiconResolve Include="com.atproto.identity.resolveHandle" />
</ItemGroup>

This tells the CarpaNet source generator to produce abstract controller classes alongside the usual data model types.

2. Implement the generated controllers

The generator creates abstract controllers grouped by NSID namespace. Subclass them and implement the abstract methods:

using CarpaNet.AspNetCore;
using Microsoft.AspNetCore.Http.HttpResults;

public class MyServerController : Xrpc.ComAtproto.Server.ServerController
{
    public override Task<Results<Ok<ComAtproto.Server.DescribeServerOutput>, ATErrorResult>> DescribeServerAsync(
        CancellationToken cancellationToken = default)
    {
        var output = new ComAtproto.Server.DescribeServerOutput
        {
            AvailableUserDomains = new List<string> { ".example.com" },
            Did = new CarpaNet.ATDid("did:web:example.com"),
        };

        return Task.FromResult<Results<Ok<ComAtproto.Server.DescribeServerOutput>, ATErrorResult>>(
            TypedResults.Ok(output));
    }
}

3. Wire up ASP.NET

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();

var app = builder.Build();
app.MapControllers();
app.Run();

Your endpoints are now available at /xrpc/{nsid} (e.g., /xrpc/com.atproto.server.describeServer).

How It Works

The CarpaNet source generator reads ATProtocol lexicon JSON files and produces:

  • Data model classes — Records, objects, input/output types (generated by the existing pipeline)
  • Abstract controllers — One per NSID namespace group (e.g., ServerController for com.atproto.server.*)

Lexicon queries map to [HttpGet] with [FromQuery] parameters. Lexicon procedures map to [HttpPost] with [FromBody] input.

Generated Controller Pattern

Lexicon: com.atproto.identity.resolveHandle (query)
  ↓
Xrpc.ComAtproto.Identity.IdentityController (abstract)
  → ResolveHandleAsync([FromQuery] string handle, CancellationToken ct)
  → Returns Task<Results<Ok<ResolveHandleOutput>, ATErrorResult>>
Lexicon: com.atproto.repo.createRecord (procedure)
  ↓
Xrpc.ComAtproto.Repo.RepoController (abstract)
  → CreateRecordAsync([FromBody] CreateRecordInput input, CancellationToken ct)
  → Returns Task<Results<Ok<CreateRecordOutput>, ATErrorResult>>

Error Handling

Use ATErrorResult factory methods to return ATProtocol-compliant error responses:

// Returns { "error": "NotFound", "message": "Record not found" } with HTTP 404
return ATErrorResult.NotFound("Record not found");

// Returns { "error": "AuthMissing", "message": "Authentication Required" } with HTTP 401
return ATErrorResult.Unauthorized();

// Returns { "error": "BadRequest", "message": "Invalid handle format" } with HTTP 400
return ATErrorResult.BadRequest("Invalid handle format");

Available factory methods:

Method Status Code Error Type
BadRequest() 400 BadRequest
Unauthorized() 401 AuthMissing
Forbidden() 403 Forbidden
NotFound() 404 NotFound
PayloadTooLarge() 413 PayloadTooLarge
TooManyRequests() 429 TooManyRequests
InternalServerError() 500 InternalServerError
NotImplemented() 501 NotImplemented
BadGateway() 502 BadGateway
ServiceUnavailable() 503 ServiceUnavailable
GatewayTimeout() 504 GatewayTimeout

MSBuild Properties

Property Description Default
CarpaNet_EmitXrpcEndpoints Enable XRPC controller generation false
Product 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
1.0.1 84 3/30/2026
0.1.0-alpha.76 39 3/30/2026
0.1.0-alpha.71 52 3/24/2026