关于 aspnet-core
面向 ASP.NET Core Web API 开发的指南,涵盖控制器设计、中间件、缓存、身份验证、验证、配置和文档。
主要功能
- 01REST 控制器设计实践
- 02中间件顺序与自定义
- 03缓存与 JWT 身份验证指引
- 04授权与验证模式
- 05配置与 Swagger/OpenAPI
适用场景
- 01规划 ASP.NET Core API 项目结构
- 02实现 JWT 身份验证与授权策略
- 03添加输入验证和全局错误处理
- 04使用 Swagger 编写 API 文档
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mindrally/ skills --skill aspnet-core安装后在 Claude Code 中输入/aspnet-core确认已加载。
详细介绍
ASP.NET Core 开发指南
你是 ASP.NET Core 开发专家,深入了解 Web API 设计、身份验证、中间件和性能优化。
项目结构
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
控制器设计
RESTful 控制器
[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);
}
}
最佳实践
- 保持控制器精简
- 使用 DTO 处理请求和响应
- 返回适当的状态码
- 始终使用 async/await
- 实施适当的验证
中间件
自定义中间件
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);
}
}
中间件顺序
- 异常处理
- HTTPS 重定向
- 静态文件
- 路由
- CORS
- 身份验证
- 授权
- 自定义中间件
- 端点
缓存
响应缓存
[HttpGet]
[ResponseCache(Duration = 60)]
public async Task<ActionResult<IEnumerable<ProductDto>>> GetProducts()
内存缓存
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);
});
}
}
分布式缓存
- 在多服务器场景中使用 Redis
- 在 Program.cs 中配置
- 使用
IDistributedCache接口
身份验证
JWT 配置
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"]!))
};
});
令牌生成
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);
}
授权
基于策略的授权
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)
错误处理
全局异常处理程序
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
});
}
});
});
验证
FluentValidation
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();
}
}
配置
选项模式
builder.Services.Configure<SmtpSettings>(builder.Configuration.GetSection("Smtp"));
public class EmailService
{
private readonly SmtpSettings _settings;
public EmailService(IOptions<SmtpSettings> options)
{
_settings = options.Value;
}
}
文档
Swagger/OpenAPI
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"
});
});
评论
支持 Markdown