Minimal API必须用.NET 6+,因底层依赖ASP.NET Core 6+新路由和中间件模型;需确保.csproj中TargetFramework为net6.0或更高,修改后执行dotnet clean再build;所有配置、路由、服务注册集中于Program.cs,且顺序严格:builder初始化→服务注册→builder.Build()→中间件配置→app.Run()前完成MapGet/MapPost;参数绑定依类型自动推断来源,复杂类型默认JSON反序列化;返回值必须用Results.*()工厂方法,不可直接return对象。

Minimal API必须用.NET 6+,.NET 5及以下不支持
Minimal API是.NET 6引入的轻量级Web API开发方式,底层依赖ASP.NET Core 6+ 的新路由和中间件模型。如果你在.NET 5项目里写MapGet却报错“找不到该扩展方法”,大概率是目标框架没升级。检查.csproj中的是否为net6.0或更高(如net8.0)。
常见误操作:用Visual Studio新建项目时选了“.NET 5 Web API”模板,之后手动改TargetFramework但没清理obj和bin目录,导致编译缓存干扰——建议改完后执行dotnet clean再dotnet build。
从Program.cs开始写,不再需要Startup.cs
Minimal API把配置、路由、服务注册全压进一个Program.cs文件。入口逻辑变短,但对顺序敏感:
-
var builder = WebApplication.CreateBuilder(args);必须在最前,它初始化配置、日志、DI容器 - 服务注册(如
builder.Services.AddDbContext())要放在builder.Build()之前 -
var app = builder.Build();之后才能调用app.MapGet、app.UseRouting等中间件方法 - 路由映射(
MapGet/MapPost)必须在app.Run()之前,否则请求进不来
典型错误:把app.MapGet("/test", () => "ok");写在app.Run()后面,结果启动成功但所有接口404。
MapGet和MapPost的参数绑定规则和传统Controller不同
Minimal API不走[FromQuery]/[FromBody]等特性,而是靠参数类型和名称自动推断来源:
- 简单类型(
string、int、Guid)默认从查询字符串或路由段绑定,如MapGet("/user/{id}", (int id) => ...) - 复杂类型(如
UserDto)默认尝试从RequestBody反序列化JSON,要求Content-Type为application/json - 想显式指定来源,得用
AsParameters或BindAsync自定义绑定器,不能直接加特性
示例:app.MapPost("/order", (OrderRequest req) => Results.Created($"/order/{req.Id}", req)); —— 如果前端发的是application/x-www-form-urlencoded,会直接返回400,因为Minimal API默认不解析表单数据。
返回值必须用Results.*()或IResult,不能直接return对象
这是最容易卡住新手的一点:你不能写MapGet("/ping", () => new { status = "ok" });,这样返回的是object,会被当成text/plain响应体,且状态码是200但无JSON头。
正确做法是用Results.Ok()、Results.Json()、Results.BadRequest()等工厂方法:
app.MapGet("/ping", () => Results.Ok(new { status = "ok" }));
注意:Results.Ok(obj)会自动设置Content-Type: application/json并序列化;如果需要控制序列化选项(比如忽略null值),得用Results.Json(obj, jsonOptions)传入JsonSerializerOptions实例。
另外,Results.NoContent()、Results.Redirect()这类状态码明确的方法,比自己new一个EmptyResult更安全,也更符合HTTP语义。
Minimal API看似“删代码”,实则把隐式约定变成了显式契约。路由顺序、参数来源、响应包装这些环节一旦出错,调试线索比传统MVC更少——建议初期先用Results.Problem()包裹异常,配合app.UseExceptionHandler()捕获未处理异常,避免500变成空白响应。









