REPR 是 FastEndpoints 社区归纳的 Request→Endpoint→Response 端点组织模式,Endpoint 是其落地载体,需显式定义 TRequest/TResponse 类型;SendAsync 返回具名响应类以保障 Swagger 和测试,Configure 中路径/动词错误导致 404,Pre/PostProcessor 有固定执行时机,DTO 验证应依赖 FluentValidation 自动处理。

REPR 不是框架内置的抽象接口,也不是 C# 语言特性——它是 FastEndpoints 社区对端点组织逻辑的一种模式归纳:Request → Endpoint → Response。它不强制你写三类文件,但一旦你按这个结构组织代码,路由、验证、序列化、日志、测试就自然解耦。直接上手就行,别被名字唬住。
Endpoint 是 REPR 的落地载体
这是最贴近 REPR 意图的基类,它显式声明了输入和输出契约,编译期就能约束类型流,比 EndpointWithoutRequest 或裸 Endpoint 更适合 API 契约明确的场景。
常见错误现象:SendAsync(new { ... }) 返回匿名对象 → Swagger 文档缺失响应结构,前端 TypeScript 客户端生成失败,单元测试难 mock。
- 必须定义具名
TResponse类(哪怕只含一个字段),否则FastEndpoints.Swagger无法推导200响应体 -
HandleAsync中调用SendAsync(new MyResponse { ... }),不是return,不是Ok(),也不是Results.Ok() - 若需返回不同状态码(如
400),用SendNotFound()、SendValidationFailure()等内置方法,它们会自动匹配对应 HTTP 状态,且保留TResponse类型上下文
Configure() 里写错动词或路径,会导致端点“消失”
FastEndpoints 不扫描控制器,它靠 Configure 方法里的 Get、Post、Patch 等调用注册端点。漏写、拼错、多写斜杠,API 就 404,而且没提示。
典型错误:
-
Post("/api/user")和Post("api/user")—— 后者少开头/,注册为相对路径,实际不生效 -
Get("/users/{id}")但 DTO 里没声明public string id { get; set; }→ 运行时绑定失败,返回400,但控制台无警告 - 多个端点用了相同路径+动词 → 后注册的覆盖前一个,静默丢弃(无编译错误、无启动日志)
建议:在 Configure 结尾加 AllowAnonymous() 或 RequireAuthorization() 显式声明权限,避免因中间件顺序导致认证拦截被跳过。
PreProcessor/PostProcessor 不是装饰器,是独立生命周期阶段
IPreProcessor 和 IPostProcessor 的执行时机固定:Pre 在模型绑定后、HandleAsync 前;Post 在 SendAsync 调用后、响应写出前。它们不能修改 HandleAsync 的返回值,也不能提前终止流程(除非抛异常)。
容易踩的坑:
- 在
PreProcessor里调用ctx.HttpContext.Response.WriteAsync()→ 冲突,因为SendAsync会再次尝试写响应体,触发System.InvalidOperationException: Headers are read-only - 想做请求日志,但
ctx.Request是已反序列化的对象,敏感字段(如密码)可能已被脱敏,日志内容和原始 JSON 不一致 -
PostProcessor里修改ctx.Response属性无效 —— 此时响应体已序列化完成,只能改 Header 或 StatusCode
DTO 验证失败时,不要手动 throw ValidationException
FastEndpoints 默认集成 FluentValidation,只要你的 TRequest 类有对应 IValidator 实现,验证失败会自动返回 400 + 格式化错误详情(ValidationFailure 数组)。手动 throw 只会让全局异常中间件接管,丢失标准错误结构。
关键点:
- 验证器类名必须是
TRequest名 +Validator(如MyRequestValidator),否则不自动发现 - 验证器构造函数注入的服务(如
ILogger)会被正确解析,无需额外配置 - 若需自定义 400 响应体格式,重写端点的
OnValidationFailure方法,而不是拦截异常
复杂点在于:当 DTO 包含嵌套对象或集合时,FluentValidation 的错误路径(PropertyName)默认是 Address.Street 这种,但前端表单常按 address.street 绑定 —— 这需要在验证器里显式调用 OverridePropertyName 或统一转小驼峰,否则错误定位不准。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











