aspnet-core · mindrally — Claude Code skill: ASP.NET Core guidelines
Gives your agent a set of ASP.NET Core conventions: controllers, middleware, caching, JWT and validation. Useful when an API is being written or rewritten.
npx skills add Mindrally/skills --skill aspnet-core -a claude-codeWhat aspnet-core does
The skill hands the agent a working set of ASP.NET Core conventions: a project layout with Controllers, Models, Services, Data, Middleware, Extensions and Configuration, thin controllers with DTOs on both sides, consistent async/await. Code samples are included — a RESTful controller, a request-logging middleware, caching through IMemoryCache and IDistributedCache, JWT setup, policy-based authorization, a global exception handler, FluentValidation rules and Swagger with a Bearer security definition.
Middleware order gets its own list: exception handling, HTTPS redirection, static files, routing, CORS, authentication, authorization, custom middleware, endpoints. Put CORS after authorization and preflight requests start failing, so it is worth checking Program.cs before that reaches production.
The skill is plain text and pulls in no dependencies. The samples do lean on specific libraries: FluentValidation for validators, Microsoft.AspNetCore.Authentication.JwtBearer for tokens, Redis for distributed caching. The JWT signing key comes from configuration (Jwt:Key), so an empty appsettings.json leaves the example dead in the water.
What it helps with
- split an ASP.NET Core project into layers instead of stuffing logic into controllers
- wire up JWT auth with issuer, audience and lifetime validation
- add response and memory caching without hand-managing cache keys
- get middleware into the right order
- document an API in Swagger along with the Bearer scheme
Example prompts for the agent
- Lay out my ASP.NET Core project using the structure from the aspnet-core skill
- Set up JWT authentication and an AdminOnly policy like the skill shows
- Check the middleware order in Program.cs and fix it if it's wrong
How to install aspnet-core
1Skills CLI (Vercel)
npx skills add Mindrally/skills --skill aspnet-core -a claude-code2Manually: put the files in place
~/.claude/skills/aspnet-core/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/aspnet-core/
1Skills CLI (Vercel)
npx skills add Mindrally/skills --skill aspnet-core -a codex2Manually: put the files in place
.agents/skills/aspnet-core/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add Mindrally/skills --skill aspnet-core -a cursor2Manually: put the files in place
.cursor/skills/aspnet-core/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install Mindrally/skills aspnet-core2Manually: put the files in place
.github/skills/aspnet-core/SKILL.md1Skills CLI (Vercel)
npx skills add Mindrally/skills --skill aspnet-core -a gemini-cli2Platform CLI
gemini skills install https://github.com/Mindrally/skills --path aspnet-coreManually: put the files in place
.devin/skills/aspnet-core/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add Mindrally/skills --skill aspnet-core -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about aspnet-core
How do I install aspnet-core in Claude?
Run npx skills add Mindrally/skills --skill aspnet-core -a claude-code. The skill file lands at ~/.claude/skills/aspnet-core/SKILL.md.
What does the aspnet-core skill do?
It gives the agent ASP.NET Core conventions covering project structure, controller design, middleware, caching, authentication and authorization, error handling, validation and Swagger docs.
Does it need extra libraries?
The samples use FluentValidation, Microsoft.AspNetCore.Authentication.JwtBearer and Redis for distributed caching. JWT also needs Jwt:Key, Jwt:Issuer and Jwt:Audience filled in configuration.
Source text
SKILL.md · Apache-2.0
---
name: aspnet-core
description: Guidelines for ASP.NET Core web development covering API design, authentication, caching, and best practices
metadata:
maintainer: Mindrally
source: https://github.com/Mindrally/skills
---
# ASP.NET Core Development Guidelines
You are an expert in ASP.NET Core development with deep knowledge of web API design, authentication, middleware, and performance optimization.
## Project Structure
```
src/
Controllers/ # API endpoints
Models/ # Domain models and DTOs
Services/ # Business logic
Data/ # DbContext and repositories
Middleware/ # Custom middleware
Extensions/ # Extension methods
Configuration/ # App configuration
Program.cs
appsettings.json
```
## Controller Design
### RESTful Controllers
```csharp
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private readonly IProductService _productService;
public ProductsController(IProductService productService)
{
_productService = productService;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<ProductDto>>> GetProducts()
{
var products = await _productService.GetAllAsync();
return Ok(products);
}
[HttpGet("{id}")]
public async Task<ActionResult<ProductDto>> GetProduct(int id)
{
var product = await _productService.GetByIdAsync(id);
if (product == null)
return NotFound();
return Ok(product);
}
[HttpPost]
public async Task<ActionResult<ProductDto>> CreateProduct(CreateProductDto dto)
{
var product = await _productService.CreateAsync(dto);
return CreatedAtAction(nameof(GetProduct), new { id = product.Id }, product);
}
}
```
### Best Practices
- Keep controllers thin
- Use DTOs for request/response
- Return appropriate status codes
- Use async/await consistently
- Implement proper validation
## Middleware
### Custom Middleware
```csharp
public class RequestLoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<RequestLoggingMiddleware> _logger;
public RequestLoggingMiddleware(RequestDelegate next, ILogger<RequestLoggingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
_logger.LogInformation("Request: {Method} {Path}", context.Request.Method, context.Request.Path);
await _next(context);
_logger.LogInformation("Response: {StatusCode}", context.Response.StatusCode);
}
}
```
### Middleware Order
1. Exception handling
2. HTTPS redirection
3. Static files
4. Routing
5. CORS
6. Authentication
7. Authorization
8. Custom middleware
9. Endpoints
## Caching
### Response Caching
```csharp
[HttpGet]
[ResponseCache(Duration = 60)]
public async Task<ActionResult<IEnumerable<ProductDto>>> GetProducts()
```
### Memory Caching
```csharp
public class ProductService : IProductService
{
private readonly IMemoryCache _cache;
public async Task<Product?> GetByIdAsync(int id)
{
return await _cache.GetOrCreateAsync($"product_{id}", async entry =>
{
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10);
return await _repository.GetByIdAsync(id);
});
}
}
```
### Distributed Caching
- Use Redis for multi-server scenarios
- Configure in Program.cs
- Use `IDistributedCache` interface
## Authentication
### JWT Configuration
```csharp
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"]!))
};
});
```
### Token Generation
```csharp
public string GenerateToken(User user)
{
var claims = new[]
{
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
new Claim(ClaimTypes.Email, user.Email),
new Claim(ClaimTypes.Role, user.Role)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]!));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: _config["Jwt:Issuer"],
audience: _config["Jwt:Audience"],
claims: claims,
expires: DateTime.UtcNow.AddHours(1),
signingCredentials: creds);
return new JwtSecurityTokenHandler().WriteToken(token);
}
```
## Authorization
### Policy-Based Authorization
```csharp
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
options.AddPolicy("PremiumUser", policy => policy.RequireClaim("Subscription", "Premium"));
});
[Authorize(Policy = "AdminOnly")]
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteProduct(int id)
```
## Error Handling
### Global Exception Handler
```csharp
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
context.Response.StatusCode = 500;
context.Response.ContentType = "application/json";
var error = context.Features.Get<IExceptionHandlerFeature>();
if (error != null)
{
await context.Response.WriteAsJsonAsync(new
{
error = "An error occurred",
detail = app.Environment.IsDevelopment() ? error.Error.Message : null
});
}
});
});
```
## Validation
### FluentValidation
```csharp
public class CreateProductValidator : AbstractValidator<CreateProductDto>
{
public CreateProductValidator()
{
RuleFor(x => x.Name).NotEmpty().MaximumLength(100);
RuleFor(x => x.Price).GreaterThan(0);
RuleFor(x => x.Category).NotEmpty();
}
}
```
## Configuration
### Options Pattern
```csharp
builder.Services.Configure<SmtpSettings>(builder.Configuration.GetSection("Smtp"));
public class EmailService
{
private readonly SmtpSettings _settings;
public EmailService(IOptions<SmtpSettings> options)
{
_settings = options.Value;
}
}
```
## Documentation
### Swagger/OpenAPI
```csharp
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.Http,
Scheme = "bearer",
BearerFormat = "JWT"
});
});
```
© Mindrally · Apache-2.0 · Mindrally/skills
Similar skills
Everything for Backend and APIs →aspnet-core by other authors comes first.