C#怎么实现REPR端点模式_C# FastEndpoints最小API教程【进阶】
REPR模式(Request-Endpoint-Response)通过显式定义TResponse类确保Swagger文档与类型安全;路径动词需准确,否则404;Pre/PostProcessor在固定生命周期执行且不可修改响应体;DTO验证失败由FluentValidation自动返回400,无需手动抛异常。
说 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,或者统一转换成小驼峰格式,否则错误信息定位会不准,给前端调试带来麻烦。
WPS Office是一款面向macOS用户的综合办公套件,将文字处理、电子表格、演示文稿、PDF工具、模板与云协作整合在同一应用中。它兼容常见Microsoft Office格式,支持Intel及Apple芯片Mac,基础功能可免费使用,
Shapr3D是一款面向工业设计、机械工程、建筑概念和三维打印工作流的CAD软件。Mac版采用Parasolid建模内核,支持草图约束、实体建模、工程图、可视化渲染及常见CAD格式交换,并可通过账户在多台设备之间同步项目。
REAPER是Cockos开发的数字音频工作站,提供多轨音频与MIDI录制、剪辑、处理、混音和母带制作工具。Mac版兼容Intel与Apple芯片,支持AU、VST、VST3、CLAP等插件格式,并提供高度可定制的工作流程。
AutoCAD 是 Autodesk 推出的专业计算机辅助设计软件,Windows 版支持精确二维绘图、三维实体与曲面建模、图纸标注、布局发布和任务自动化,并包含多套行业专业化工具组合,适用于建筑、机械、电气、工程建设及制造设计人员。
SketchUp Pro 是面向建筑、室内、景观、施工和产品设计等专业场景的三维建模工具,提供桌面建模、LayOut 二维文档、模型资源库、扩展程序及云端协作能力。其操作逻辑直观,适合从概念推敲、空间规划到图纸表达和方案汇报的完整工作流程。
AutoCAD LT 是 Autodesk 推出的专业二维 CAD 软件,适合建筑师、工程师、施工人员和设计师完成精确绘图、标注及文档编制。它支持 DWG 工作流、智能块、图形比较、计数、表格和 AutoLISP 自动化,













