ASP.NET Core
Trigger On
- working on ASP.NET Core apps, services, or middleware
- changing auth, routing, configuration, hosting, or deployment behavior
- deciding between ASP.NET Core sub-stacks such as Blazor, Minimal APIs, or controller APIs
- debugging request pipeline issues
- modernizing legacy ASP.NET to ASP.NET Core
Documentation
References
- patterns.md - Detailed middleware patterns, security patterns, configuration patterns, DI patterns, error handling patterns, and logging patterns
- anti-patterns.md - Common ASP.NET Core mistakes including HttpClient misuse, async anti-patterns, configuration errors, DI issues, middleware ordering problems, and security vulnerabilities
Workflow
Detect the real hosting shape first:
- top-level
Program.cs structure
- middleware order and registration
- auth model (Identity, JWT, OAuth, cookies)
- endpoint registrations and routing
Follow the correct middleware order:
ExceptionHandler → HttpsRedirection → Static Files → Routing
→ CORS → Authentication → Authorization → Rate Limiting
→ Response Caching → Custom Middleware → Endpoints
Use built-in patterns correctly:
- Prefer
IOptions<T> / IOptionsSnapshot<T> for configuration
- Use
ILogger<T> for structured logging
- Use
IHttpClientFactory for HTTP clients (never new HttpClient())
- Use
IHostedService / BackgroundService for background work
Route specialized work to specific skills:
- UI and components →
dotnet-blazor
- Real-time →
dotnet-signalr
- RPC →
dotnet-grpc
- New HTTP APIs →
dotnet-minimal-apis (prefer unless controllers needed)
- Controller APIs →
dotnet-web-api
Validate with build, tests, and targeted endpoint checks.
Middleware Patterns
Correct Order Matters
var app = builder.Build();
app.UseExceptionHandler("/error"); // 1. Catch all exceptions
app.UseHsts(); // 2. Security headers
app.UseHttpsRedirection(); // 3. HTTPS redirect
app.UseStaticFiles(); // 4. Serve static files
app.UseRouting(); // 5. Route matching
app.UseCors(); // 6. CORS policy
app.UseAuthentication(); // 7. Who are you?
app.UseAuthorization(); // 8. Can you access?
app.UseRateLimiter(); // 9. Rate limiting
app.UseResponseCaching(); // 10. Response cache
app.MapControllers(); // 11. Endpoints
Custom Middleware Pattern
public class RequestTimingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<RequestTimingMiddleware> _logger;
public RequestTimingMiddleware(RequestDelegate next, ILogger<RequestTimingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
var sw = Stopwatch.StartNew();
await _next(context);
_logger.LogInformation("Request {Path} completed in {Elapsed}ms",
context.Request.Path, sw.ElapsedMilliseconds);
}
}
Configuration Patterns
Strongly-Typed Options
// appsettings.json
{
"EmailSettings": {
"SmtpServer": "smtp.example.com",
"Port": 587
}
}
// Registration
builder.Services.Configure<EmailSettings>(
builder.Configuration.GetSection("EmailSettings"));
// Usage
public class EmailService(IOptions<EmailSettings> options)
{
private readonly EmailSettings _settings = options.Value;
}
Environment-Based Configuration
builder.Configuration
.AddJsonFile("appsettings.json", optional: false)
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables()
.AddUserSecrets<Program>(optional: true);
Security Patterns
Authentication Setup
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = builder.Configuration["Jwt:Issuer"],
ValidAudience = builder.Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]!))
};
});
Authorization Policies
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy =>
policy.RequireRole("Admin"));
options.AddPolicy("MinAge18", policy =>
policy.RequireClaim("Age", "18", "19", "20")); // simplified
});
Anti-Patterns to Avoid
| Anti-Pattern |
Why It's Bad |
Better Approach |
new HttpClient() |
Socket exhaustion |
IHttpClientFactory |
Sync-over-async (Task.Result) |
Thread pool starvation |
await properly |
Storing secrets in appsettings.json |
Security risk |
User Secrets, Key Vault |
| Catching all exceptions silently |
Hides bugs |
Use IExceptionHandler |
async void in middleware |
Crashes process |
async Task |
| Missing HTTPS redirect |
Security risk |
UseHttpsRedirection() |
Performance Best Practices
- Use async/await everywhere — avoid sync blocking calls
- Pool DbContext properly — use scoped lifetime
- Enable response compression —
UseResponseCompression()
- Use output caching —
UseOutputCache() for .NET 7+
- Profile with diagnostic tools — Visual Studio Diagnostic Tools, PerfView
- Avoid allocations in hot paths — use
Span<T>, pooling
Deliver
- production-credible ASP.NET Core code and config
- a clear request pipeline and hosting story
- verification that matches the affected endpoints and middleware
- security headers and HTTPS configured correctly
Validate
- middleware order is intentional and documented
- security and configuration changes are explicit
- endpoint behavior is covered by tests or smoke checks
- no blocking calls in async context
- secrets are not committed to source control
- health checks are implemented for production readiness
1---2name: dotnet-aspnet-core3description: Build, debug, modernize, or review ASP.NET Core applications with correct hosting, middleware, security, configuration, logging, and deployment patterns on current .NET.4---56# ASP.NET Core78## Trigger On910- working on ASP.NET Core apps, services, or middleware11- changing auth, routing, configuration, hosting, or deployment behavior12- deciding between ASP.NET Core sub-stacks such as Blazor, Minimal APIs, or controller APIs13- debugging request pipeline issues14- modernizing legacy ASP.NET to ASP.NET Core1516## Documentation1718- [ASP.NET Core Overview](https://learn.microsoft.com/en-us/aspnet/core/?view=aspnetcore-10.0)19- [ASP.NET Core Middleware](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-10.0)20- [ASP.NET Core Best Practices](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/best-practices?view=aspnetcore-10.0)21- [Configuration in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-10.0)22- [Authentication and Authorization](https://learn.microsoft.com/en-us/aspnet/core/security/?view=aspnetcore-10.0)2324### References2526- [patterns.md](references/patterns.md) - Detailed middleware patterns, security patterns, configuration patterns, DI patterns, error handling patterns, and logging patterns27- [anti-patterns.md](references/anti-patterns.md) - Common ASP.NET Core mistakes including HttpClient misuse, async anti-patterns, configuration errors, DI issues, middleware ordering problems, and security vulnerabilities2829## Workflow30311. **Detect the real hosting shape first:**32 - top-level `Program.cs` structure33 - middleware order and registration34 - auth model (Identity, JWT, OAuth, cookies)35 - endpoint registrations and routing36372. **Follow the correct middleware order:**38 ```39 ExceptionHandler → HttpsRedirection → Static Files → Routing40 → CORS → Authentication → Authorization → Rate Limiting41 → Response Caching → Custom Middleware → Endpoints42 ```43443. **Use built-in patterns correctly:**45 - Prefer `IOptions<T>` / `IOptionsSnapshot<T>` for configuration46 - Use `ILogger<T>` for structured logging47 - Use `IHttpClientFactory` for HTTP clients (never `new HttpClient()`)48 - Use `IHostedService` / `BackgroundService` for background work49504. **Route specialized work to specific skills:**51 - UI and components → `dotnet-blazor`52 - Real-time → `dotnet-signalr`53 - RPC → `dotnet-grpc`54 - New HTTP APIs → `dotnet-minimal-apis` (prefer unless controllers needed)55 - Controller APIs → `dotnet-web-api`56575. **Validate with build, tests, and targeted endpoint checks.**5859## Middleware Patterns6061### Correct Order Matters62```csharp63var app = builder.Build();6465app.UseExceptionHandler("/error"); // 1. Catch all exceptions66app.UseHsts(); // 2. Security headers67app.UseHttpsRedirection(); // 3. HTTPS redirect68app.UseStaticFiles(); // 4. Serve static files69app.UseRouting(); // 5. Route matching70app.UseCors(); // 6. CORS policy71app.UseAuthentication(); // 7. Who are you?72app.UseAuthorization(); // 8. Can you access?73app.UseRateLimiter(); // 9. Rate limiting74app.UseResponseCaching(); // 10. Response cache75app.MapControllers(); // 11. Endpoints76```7778### Custom Middleware Pattern79```csharp80public class RequestTimingMiddleware81{82 private readonly RequestDelegate _next;83 private readonly ILogger<RequestTimingMiddleware> _logger;8485 public RequestTimingMiddleware(RequestDelegate next, ILogger<RequestTimingMiddleware> logger)86 {87 _next = next;88 _logger = logger;89 }9091 public async Task InvokeAsync(HttpContext context)92 {93 var sw = Stopwatch.StartNew();94 await _next(context);95 _logger.LogInformation("Request {Path} completed in {Elapsed}ms",96 context.Request.Path, sw.ElapsedMilliseconds);97 }98}99```100101## Configuration Patterns102103### Strongly-Typed Options104```csharp105// appsettings.json106{107 "EmailSettings": {108 "SmtpServer": "smtp.example.com",109 "Port": 587110 }111}112113// Registration114builder.Services.Configure<EmailSettings>(115 builder.Configuration.GetSection("EmailSettings"));116117// Usage118public class EmailService(IOptions<EmailSettings> options)119{120 private readonly EmailSettings _settings = options.Value;121}122```123124### Environment-Based Configuration125```csharp126builder.Configuration127 .AddJsonFile("appsettings.json", optional: false)128 .AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true)129 .AddEnvironmentVariables()130 .AddUserSecrets<Program>(optional: true);131```132133## Security Patterns134135### Authentication Setup136```csharp137builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)138 .AddJwtBearer(options =>139 {140 options.TokenValidationParameters = new TokenValidationParameters141 {142 ValidateIssuer = true,143 ValidateAudience = true,144 ValidateLifetime = true,145 ValidateIssuerSigningKey = true,146 ValidIssuer = builder.Configuration["Jwt:Issuer"],147 ValidAudience = builder.Configuration["Jwt:Audience"],148 IssuerSigningKey = new SymmetricSecurityKey(149 Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]!))150 };151 });152```153154### Authorization Policies155```csharp156builder.Services.AddAuthorization(options =>157{158 options.AddPolicy("AdminOnly", policy =>159 policy.RequireRole("Admin"));160 options.AddPolicy("MinAge18", policy =>161 policy.RequireClaim("Age", "18", "19", "20")); // simplified162});163```164165## Anti-Patterns to Avoid166167| Anti-Pattern | Why It's Bad | Better Approach |168|--------------|--------------|-----------------|169| `new HttpClient()` | Socket exhaustion | `IHttpClientFactory` |170| Sync-over-async (`Task.Result`) | Thread pool starvation | `await` properly |171| Storing secrets in `appsettings.json` | Security risk | User Secrets, Key Vault |172| Catching all exceptions silently | Hides bugs | Use `IExceptionHandler` |173| `async void` in middleware | Crashes process | `async Task` |174| Missing HTTPS redirect | Security risk | `UseHttpsRedirection()` |175176## Performance Best Practices1771781. **Use async/await everywhere** — avoid sync blocking calls1792. **Pool DbContext properly** — use scoped lifetime1803. **Enable response compression** — `UseResponseCompression()`1814. **Use output caching** — `UseOutputCache()` for .NET 7+1825. **Profile with diagnostic tools** — Visual Studio Diagnostic Tools, PerfView1836. **Avoid allocations in hot paths** — use `Span<T>`, pooling184185## Deliver186187- production-credible ASP.NET Core code and config188- a clear request pipeline and hosting story189- verification that matches the affected endpoints and middleware190- security headers and HTTPS configured correctly191192## Validate193194- middleware order is intentional and documented195- security and configuration changes are explicit196- endpoint behavior is covered by tests or smoke checks197- no blocking calls in async context198- secrets are not committed to source control199- health checks are implemented for production readiness