Minimal API 是 ASP.NET Core 6+ 提供的轻量级路由定义方式,绕过 Controller 和 MVC 模式,用 MapGet/MapPost 直接注册端点;它启动快、内存低、代码少,但无内置过滤器、自动验证、视图支持,需手动配置依赖注入、验证和中间件。

Minimal API 是什么,和传统 Controller 有啥区别
Minimal API 不是新语言或框架,它是 ASP.NET Core 6+ 提供的一套轻量级路由定义方式,核心就是绕过 Controller 类和 MVC 模式,直接用 WebApplication.CreateBuilder + MapGet/MapPost 等扩展方法注册端点。它不强制依赖 IActionResult、模型绑定管道、视图引擎这些——如果你只写 JSON API、内部服务、健康检查、简单代理,那它启动更快、内存占用更低、代码行数更少。
但别误以为“最小”等于“万能”:没内置过滤器链、没自动模型验证(除非手动加 ValidateModel)、没区域/视图支持、依赖注入配置也得自己显式写清楚。
怎么从零写一个 Minimal API 的 GET 接口
最简可行版本只需要三步:
- 创建项目时选
dotnet new web(不是webapi或mvc) - 在
Program.cs里删掉所有模板代码,只留:var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); </li></ul><p>app.MapGet("/hello", () => "Hello World");</p><p>app.Run();- 运行后访问
<a href="https://www.php.cn/link/34e81352505555b8fea122cba1403273">https://www.php.cn/link/34e81352505555b8fea122cba1403273</a>就能返回文本
注意几个关键点:
-
MapGet第二个参数是Func<iresult></iresult>或直接返回可序列化对象(如string、int),框架会自动包装成Results.Ok(...) - 如果返回的是复杂类型(比如
new { Name = "Alice" }),默认走 System.Text.Json 序列化,不走 Newtonsoft.Json - 不要试图在
MapGet回调里直接 throwException来模拟错误响应——得用Results.Problem(...)或Results.StatusCode(404)才能被中间件正确处理
POST 接口怎么接收 JSON 数据并校验
Minimal API 默认支持模型绑定,但不像 Controller 那样自动扫描
[FromBody]特性。你得显式告诉它“这个参数来自请求体”:app.MapPost("/users", (User user) => { if (!ModelState.IsValid) return Results.BadRequest(ModelState); <pre class="brush:php;toolbar:false;">return Results.Created($"/users/{user.Id}", user);});
这里容易踩的坑:
-
User类必须有无参构造函数,且属性为 public set(否则绑定失败,user会是 null) - 校验靠
ModelState,但它不会自动触发——得手动加[ApiController]特性?不行,Minimal API 里没这玩意儿。正确做法是提前注册验证服务:builder.Services.AddControllers().AddJsonOptions(...)不起作用;应该用builder.Services.AddEndpointsApiExplorer()+builder.Services.AddValidation()(.NET 7+)或手动调Validator.TryValidateObject - 更推荐的做法是:把验证逻辑封装进 record 或使用
AsParameters+BindAsync自定义绑定器,避免裸露ModelState
依赖注入怎么在 Minimal API 里用
所有通过
builder.Services注册的服务,都能在MapXxx的委托参数里按类型注入,比如:builder.Services.AddSingleton<IUserService, UserService>(); <p>app.MapGet("/users/{id}", (int id, IUserService service) => { var user = service.GetById(id); return user is null ? Results.NotFound() : Results.Ok(user); });注意:
- 参数顺序无关紧要,框架按类型匹配
- 如果同时需要
HttpContext和自定义服务,HttpContext必须声明为第一个参数(这是硬规则) - 不支持在 lambda 里直接 new 对象然后期望 DI 注入其依赖——DI 只作用于 Map 方法的参数层
- 日志、配置等基础服务(
ILogger<t></t>、IConfiguration)也都可直接当参数写,无需额外注册
Minimal API 看似简单,但一旦涉及跨域、JWT 验证、全局异常处理、OpenAPI 文档生成,就得补一堆中间件和配置项,这时候“最小”的代价其实是心智负担转移了——不是写得少,而是得更清楚每一步谁在起作用。
- 运行后访问


















