aspnet-core · mindrally — скилл для Claude Code: правила ASP.NET Core
Задаёт агенту правила разработки на ASP.NET Core: контроллеры, middleware, кэш, JWT и валидация. Пригодится, когда API пишется с нуля или переписывается.
npx skills add Mindrally/skills --skill aspnet-core -a claude-codeЧто делает aspnet-core
Скилл подкладывает агенту набор соглашений по ASP.NET Core: структура проекта с папками Controllers, Models, Services, Data, Middleware, Extensions и Configuration, тонкие контроллеры с DTO на входе и выходе, единый async/await. Внутри есть готовые примеры кода — RESTful-контроллер, кастомный middleware логирования, кэширование через IMemoryCache и IDistributedCache, настройка JWT, политики авторизации, глобальный обработчик исключений, FluentValidation и Swagger с описанием Bearer-схемы.
Отдельно расписан порядок middleware: обработка исключений, редирект на HTTPS, статика, роутинг, CORS, аутентификация, авторизация, свои обработчики, эндпоинты. Если поставить CORS после авторизации, preflight-запросы начнут отваливаться — это повод сверить Program.cs до того, как что-то сломается в проде.
Скилл текстовый, зависимостей не тянет. Но примеры опираются на конкретные библиотеки: FluentValidation для валидаторов, Microsoft.AspNetCore.Authentication.JwtBearer для токенов, Redis для распределённого кэша. Ключ подписи JWT берётся из конфигурации (Jwt:Key), так что без заполненного appsettings.json пример не заработает.
Какие задачи решает
- разложить проект ASP.NET Core по слоям и не смешать логику в контроллерах
- настроить JWT-аутентификацию с валидацией issuer, audience и lifetime
- добавить кэш ответов и памяти без ручного управления ключами
- выстроить middleware в правильном порядке
- описать API в Swagger вместе со схемой Bearer-токена
Примеры запросов агенту
- Разбей мой ASP.NET Core проект по структуре из скилла aspnet-core
- Настрой JWT-аутентификацию и политику AdminOnly по примеру из скилла
- Проверь порядок middleware в Program.cs и поправь, если он нарушен
Как установить aspnet-core
1Через Skills CLI (Vercel)
npx skills add Mindrally/skills --skill aspnet-core -a claude-code2Вручную: положить файлы
~/.claude/skills/aspnet-core/SKILL.mdПапка скилла целиком; для одного проекта — .claude/skills/aspnet-core/
1Через Skills CLI (Vercel)
npx skills add Mindrally/skills --skill aspnet-core -a codex2Вручную: положить файлы
.agents/skills/aspnet-core/SKILL.mdДля всех проектов — ~/.agents/skills/
1Через Skills CLI (Vercel)
npx skills add Mindrally/skills --skill aspnet-core -a cursor2Вручную: положить файлы
.cursor/skills/aspnet-core/SKILL.mdCursor читает и .agents/skills/, и .claude/skills/
1GitHub CLI
gh skill install Mindrally/skills aspnet-core2Вручную: положить файлы
.github/skills/aspnet-core/SKILL.md1Через Skills CLI (Vercel)
npx skills add Mindrally/skills --skill aspnet-core -a gemini-cli2Командой платформы
gemini skills install https://github.com/Mindrally/skills --path aspnet-coreВручную: положить файлы
.devin/skills/aspnet-core/SKILL.mdСтарый путь .windsurf/skills/ тоже читается
Через Skills CLI (Vercel)
npx skills add Mindrally/skills --skill aspnet-core -a opencodeClaude.ai
Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills
По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов
Из того же набора160
Другие версии aspnet-core
Похожие
Рядом в теме «Бэкенд и API»
Всё по теме «Бэкенд и API» →Вопросы о aspnet-core
Как установить aspnet-core в Claude?
Выполните npx skills add Mindrally/skills --skill aspnet-core -a claude-code. Файл скилла окажется по пути ~/.claude/skills/aspnet-core/SKILL.md.
Что делает скилл aspnet-core?
Даёт агенту соглашения по разработке на ASP.NET Core: структура проекта, дизайн контроллеров, middleware, кэширование, аутентификация и авторизация, обработка ошибок, валидация и документация Swagger.
Нужны ли дополнительные библиотеки?
Примеры кода используют FluentValidation, Microsoft.AspNetCore.Authentication.JwtBearer и Redis для распределённого кэша. Для JWT понадобится заполнить Jwt:Key, Jwt:Issuer и Jwt:Audience в конфигурации.
Исходный текст
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