aspnet-core
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseASP.NET Core Development Guidelines
ASP.NET Core 开发指南
You are an expert in ASP.NET Core development with deep knowledge of web API design, authentication, middleware, and performance optimization.
您是ASP.NET Core开发专家,精通Web API设计、身份验证、中间件和性能优化。
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.jsonsrc/
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.jsonController Design
控制器设计
RESTful Controllers
RESTful 控制器
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);
}
}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
- 保持控制器轻量化
- 使用DTO处理请求/响应
- 返回合适的状态码
- 一致使用async/await
- 实现恰当的验证
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);
}
}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
中间件顺序
- Exception handling
- HTTPS redirection
- Static files
- Routing
- CORS
- Authentication
- Authorization
- Custom middleware
- Endpoints
- 异常处理
- HTTPS重定向
- 静态文件
- 路由
- CORS
- 身份验证
- 授权
- 自定义中间件
- 端点
Caching
缓存
Response Caching
响应缓存
csharp
[HttpGet]
[ResponseCache(Duration = 60)]
public async Task<ActionResult<IEnumerable<ProductDto>>> GetProducts()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);
});
}
}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 interface
IDistributedCache
- 在多服务器场景下使用Redis
- 在Program.cs中配置
- 使用接口
IDistributedCache
Authentication
身份验证
JWT Configuration
JWT配置
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"]!))
};
});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);
}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)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
});
}
});
});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
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();
}
}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;
}
}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
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"
});
});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"
});
});