# How AI Agents Assist with ASP.NET Core Development Using dotnet-aspnetcore Skills

> Discover how AI agents streamline ASP.NET Core development using dotnet-aspnetcore skills. Generate secure, compliant code with Microsoft-approved patterns and examples.

- Repository: [.NET Platform/skills](https://github.com/dotnet/skills)
- Tags: how-to-guide
- Published: 2026-07-06

---

**AI agents use the markdown-based skill definitions in the `dotnet/skills` repository to generate secure, standards-compliant ASP.NET Core code by following Microsoft-approved architectural patterns, validation checklists, and concrete implementation examples.**

The `dotnet-aspnetcore` plugin within the `dotnet/skills` repository provides structured skill definitions that transform AI agents from guesswork-based assistants into knowledge-driven code generators. These skills are self-contained Markdown files living under `plugins/dotnet-aspnetcore/skills/`, enabling agents to reason about project requirements and emit production-ready minimal APIs, Web API endpoints, and observability configurations that align with current .NET best practices.

## How AI Agents Use dotnet-aspnetcore Skill Definitions

The agent workflow follows a deterministic six-step process defined by the skill architecture. Each skill file contains "When to Use" contexts, "Workflow" steps, "Common Mistakes" to avoid, and concrete code snippets that guide the agent's reasoning.

### Step 1: Identify the Problem and Select the Skill

When a developer requests a feature such as "file upload in a minimal API" or "create a new Web API endpoint," the agent parses the request and extracts the relevant skill identifier. For file handling scenarios, the agent selects `minimal-api-file-upload`; for standard REST APIs, it selects `dotnet-webapi`.

### Step 2: Load the Skill Description from Markdown

The agent reads the skill's [`SKILL.md`](https://github.com/dotnet/skills/blob/main/SKILL.md) file to ingest the architectural requirements. Key files include:
- **[`plugins/dotnet-aspnetcore/skills/minimal-api-file-upload/SKILL.md`](https://github.com/dotnet/skills/blob/main/plugins/dotnet-aspnetcore/skills/minimal-api-file-upload/SKILL.md)** – Defines secure upload patterns with anti-forgery and size limits.
- **[`plugins/dotnet-aspnetcore/skills/dotnet-webapi/SKILL.md`](https://github.com/dotnet/skills/blob/main/plugins/dotnet-aspnetcore/skills/dotnet-webapi/SKILL.md)** – Covers DTO conventions, `TypedResults` usage, and OpenAPI configuration.
- **[`plugins/dotnet-aspnetcore/skills/configuring-opentelemetry-dotnet/SKILL.md`](https://github.com/dotnet/skills/blob/main/plugins/dotnet-aspnetcore/skills/configuring-opentelemetry-dotnet/SKILL.md)** – Specifies tracing and exporter pipeline setup.

### Step 3: Derive the Architectural Plan

From the "Workflow" sections in these Markdown files, the agent constructs a high-level implementation plan. For a file upload feature, this includes configuring Kestrel limits, adding antiforgery policies, creating validation logic, and mapping endpoints. For Web APIs, the plan involves defining sealed-record DTOs, service interfaces, and typed result patterns.

### Step 4: Generate Code Aligned with Best Practices

The agent emits C# snippets that follow the exact patterns shown in the skill files. Generated code is inserted into appropriate project locations, typically [`Program.cs`](https://github.com/dotnet/skills/blob/main/Program.cs) for minimal APIs. The agent uses signatures like `TypedResults`, `IFormFile`, and `AddOpenApi` as specified in the skill definitions, ensuring compatibility with .NET 9+ built-in OpenAPI providers rather than external dependencies like Swashbuckle.

### Step 5: Validate Against the Skill Checklist

The agent runs verification against the skill's "Validation" checklist, typically found around line 600 in the `dotnet-webapi` skill. This programmatic verification ensures that endpoints return correct HTTP status codes, anti-forgery tokens are properly configured (or explicitly disabled for API-only scenarios), and file uploads respect magic-byte validation.

### Step 6: Document and Test the Implementation

Following the skill's "Create a .http test file" step, the agent generates `.http` files with example requests and updates OpenAPI metadata. This closes the loop by providing runnable documentation that matches the implemented architecture.

## Code Generation Examples from dotnet-aspnetcore Skills

### Minimal API File Upload with Security-First Patterns

The `minimal-api-file-upload` skill enforces dual size-limit configuration and magic-byte validation to prevent security vulnerabilities. The generated code configures both Kestrel server limits and FormOptions, then validates file content types against actual file headers rather than just the `Content-Type` header.

```csharp
var builder = WebApplication.CreateBuilder(args);

// Configure request-size limits (both Kestrel and FormOptions)
builder.WebHost.ConfigureKestrel(o => o.Limits.MaxRequestBodySize = 10 * 1024 * 1024);
builder.Services.Configure<FormOptions>(o => o.MultipartBodyLengthLimit = 10 * 1024 * 1024);

var app = builder.Build();

app.MapPost("/upload", async (IFormFile file) =>
{
    // Verify content type against magic bytes
    var allowed = new[] { "image/jpeg", "image/png" };
    if (!allowed.Contains(file.ContentType, StringComparer.OrdinalIgnoreCase))
        return Results.BadRequest("File type not allowed");

    await using var stream = file.OpenReadStream();
    var header = new byte[8];
    await stream.ReadAsync(header);
    var isJpeg = header[0] == 0xFF && header[1] == 0xD8 && header[2] == 0xFF;
    var isPng  = header[0] == 0x89 && header[1] == 0x50 && header[2] == 0x4E && header[3] == 0x47;
    var detected = isJpeg ? "image/jpeg" : isPng ? "image/png" : null;
    if (detected is null || !string.Equals(file.ContentType, detected, StringComparison.OrdinalIgnoreCase))
        return Results.BadRequest("Mismatched content type");

    var safeName = $"{Guid.NewGuid()}{(detected == "image/jpeg" ? ".jpg" : ".png")}";
    var path = Path.Combine("uploads", safeName);
    Directory.CreateDirectory("uploads");
    await using var outFile = File.Create(path);
    stream.Position = 0;
    await stream.CopyToAsync(outFile);
    return Results.Ok(new { FileName = safeName, file.Length });
}).DisableAntiforgery(); // API-only endpoint

app.Run();

```

Key enforcements from the skill include explicit anti-forgery opt-out for API endpoints, safe filename generation using `Guid.NewGuid()`, and content-type validation against file magic bytes rather than trusting client headers.

### Building Typed CRUD Endpoints with Sealed Record DTOs

The `dotnet-webapi` skill mandates sealed-record DTOs for immutable data contracts and `TypedResults` for compile-time OpenAPI inference. The agent generates service interfaces with `CancellationToken` support and maps endpoints using explicit return types.

```csharp
// DTOs – sealed records with XML comments (auto-included in OpenAPI)
/// <summary>Request payload for creating a product.</summary>
public sealed record CreateProductRequest(string Name, decimal Price, string Category);

/// <summary>Response payload for a product.</summary>
public sealed record ProductResponse(int Id, string Name, decimal Price, string Category, DateTimeOffset CreatedAt);

// Service interface (DI-friendly)
public interface IProductService
{
    Task<IReadOnlyList<ProductResponse>> GetAllAsync(CancellationToken ct);
    Task<ProductResponse?> GetByIdAsync(int id, CancellationToken ct);
    Task<ProductResponse> CreateAsync(CreateProductRequest req, CancellationToken ct);
}

// Minimal-API registration (TypedResults with explicit return type)
app.MapGet("/api/products", async (IProductService svc, CancellationToken ct) =>
    TypedResults.Ok(await svc.GetAllAsync(ct)));

app.MapGet("/api/products/{id:int}", async (int id, IProductService svc, CancellationToken ct) =>
    await svc.GetByIdAsync(id, ct) is { } p
        ? TypedResults.Ok(p)
        : TypedResults.NotFound());

app.MapPost("/api/products", async (CreateProductRequest req, IProductService svc, CancellationToken ct) =>
{
    var created = await svc.CreateAsync(req, ct);
    return TypedResults.Created($"/api/products/{created.Id}", created);
});

```

The skill requires `DateTimeOffset` for timestamps to ensure timezone-aware data, and the agent configures `AddProblemDetails` globally for standardized error responses.

### Configuring OpenTelemetry for Observability

The `configuring-opentelemetry-dotnet` skill guides agents to add tracing pipelines using only built-in extensions compatible with the target framework, avoiding version conflicts.

```csharp
builder.Services.AddOpenTelemetry()
    .WithTracing(tracerProvider => tracerProvider
        .AddAspNetCoreInstrumentation()
        .AddHttpClientInstrumentation()
        .AddJaegerExporter(opts =>
        {
            opts.AgentHost = builder.Configuration["Jaeger:Host"];
            opts.AgentPort = int.Parse(builder.Configuration["Jaeger:Port"]);
        }));

var app = builder.Build();
app.UseOpenTelemetryPrometheusScrapingEndpoint(); // expose /metrics

```

This configuration ensures the agent adds instrumentation without pulling in incompatible third-party packages, maintaining the zero-dependency approach recommended for .NET 9+ projects.

## Architectural Benefits of Knowledge-Driven AI Agents

- **Consistent API Design** – All generated endpoints use sealed-record DTOs, `TypedResults`, and proper HTTP status codes (e.g., `201 Created` with `Location` headers) as defined in [`dotnet-webapi/SKILL.md`](https://github.com/dotnet/skills/blob/main/dotnet-webapi/SKILL.md).
- **Security-First Defaults** – The `minimal-api-file-upload` skill enforces anti-forgery tokens, request size limits, and content-type validation, while the Web API skill mandates `AddProblemDetails` for error handling.
- **OpenTelemetry Ready** – Agents automatically configure tracing and exporters using the `configuring-opentelemetry-dotnet` skill, ensuring observability without manual instrumentation.
- **Zero-Dependency Generation** – For .NET 9+, the skills specify the built-in `AddOpenApi` provider instead of external libraries like Swashbuckle, preventing package version conflicts.
- **Test-Driven Workflow** – Each skill's validation checklist (located around line 600 in the `dotnet-webapi` skill) guides the agent to verify that all endpoints return correct status codes and handle errors appropriately.

## Summary

- AI agents use markdown-based skill definitions from `plugins/dotnet-aspnetcore/skills/` to reason about ASP.NET Core architecture and generate code.
- The workflow involves six steps: problem identification, skill loading, architectural planning, code generation, validation against checklists, and documentation creation.
- Generated code follows specific patterns including sealed-record DTOs, `TypedResults`, magic-byte validation for file uploads, and built-in OpenAPI providers.
- Security enforcements include anti-forgery configuration, request size limits, and `ProblemDetails` error handling.
- The self-contained nature of skill files ensures agents remain up-to-date with latest Microsoft conventions without external heuristics.

## Frequently Asked Questions

### What is the dotnet-aspnetcore skill plugin?

The `dotnet-aspnetcore` plugin is a collection of Markdown-based skill definitions located in the `dotnet/skills` repository under `plugins/dotnet-aspnetcore/`. Each skill, declared in [`plugin.json`](https://github.com/dotnet/skills/blob/main/plugin.json), contains architectural patterns, code snippets, and validation checklists that AI agents use to generate ASP.NET Core code following Microsoft best practices.

### How does an AI agent validate generated code against skills?

The agent uses the "Validation" checklist section found in each skill file (approximately line 600 in [`dotnet-webapi/SKILL.md`](https://github.com/dotnet/skills/blob/main/dotnet-webapi/SKILL.md)) to programmatically verify the implementation. This includes checking that endpoints return correct HTTP status codes, file uploads respect size limits configured in `ConfigureKestrel` and `FormOptions`, and anti-forgery policies are properly applied or explicitly disabled for API endpoints.

### What security patterns are enforced by the minimal-api-file-upload skill?

The skill mandates dual request-size limits via `builder.WebHost.ConfigureKestrel` and `builder.Services.Configure<FormOptions>`, magic-byte validation to verify file types against actual headers rather than `Content-Type` strings, safe filename generation using `Guid.NewGuid()`, and explicit anti-forgery opt-out via `.DisableAntiforgery()` for API-only endpoints.

### How do skills ensure OpenAPI compatibility without external dependencies?

The `dotnet-webapi` skill instructs agents to use `AddOpenApi()` and `WithOpenApi()` methods built into .NET 9+ instead of third-party packages like Swashbuckle. This zero-dependency approach prevents version conflicts and ensures the generated OpenAPI documentation uses native framework features for schema inference and endpoint metadata.