下面给出一份「系统化」的梳理,将 ASP.NET Core Web API 中 GET 与 POST 常见的传值方式按**"在哪儿传" → "怎么拿" → "注意什么"**三个维度展开,并给出最小可运行代码片段。阅读完后你可以直接当"速查表"使用。
一、GET 请求的传值方式
1. 路由段(Route Segment)
-
在哪儿传 :URL 路径本身。
bashGET /products/123/orders/456
-
怎么拿 :
[HttpGet]
模板上声明占位符 + 同名参数 /[FromRoute]
显式标记。csharp[HttpGet("products/{productId}/orders/{orderId}")] public IActionResult Get(int productId, int orderId) { ... }
-
注意 :
- 占位符大小写不敏感。
- 若参数名与模板不一致,用
[FromRoute(Name = "xxx")]
手动绑定。
2. 查询字符串(Query String)
-
在哪儿传 :
?
后的键值对。iniGET /search?q=dotnet&page=2
-
怎么拿 :
-
简单类型:框架自动按名称绑定。
csharp[HttpGet("search")] public IActionResult Search(string q, int page = 1) { ... }
-
复杂类型:定义一个 DTO 并用
[FromQuery]
。csharppublic class SearchDto { public string Q { get; set; } public int Page { get; set; } = 1; } [HttpGet("search")] public IActionResult Search([FromQuery] SearchDto dto) { ... }
-
-
注意 :
- 数组/列表:
tags=1&tags=2&tags=3
→List<int> tags
自动接收。 - 大小写不敏感,可用
[BindRequired]
、[BindNever]
精细控制。
- 数组/列表:
3. 请求头(Header)
-
在哪儿传 :HTTP 头。
makefileX-Api-Version: 2
-
怎么拿 :
csharp[HttpGet("ping")] public IActionResult Ping([FromHeader(Name = "X-Api-Version")] string version) { ... }
4. 服务容器(DI)
-
在哪儿传 :不来自客户端,而是框架自动注入。
csharp[HttpGet("time")] public IActionResult GetTime(ILogger<WeatherController> logger) { ... }
二、POST 请求的传值方式
1. 请求体(Body)
-
在哪儿传:JSON / XML / form-data / plain text 等。
jsonPOST /orders { "productId": 123, "quantity": 2 }
-
怎么拿:
-
JSON →
[FromBody]
反序列化。csharppublic class CreateOrderDto { public int ProductId { get; set; } public int Quantity { get; set; } } [HttpPost("orders")] public IActionResult Create([FromBody] CreateOrderDto dto) { ... }
-
支持多种格式:通过
Content-Type
自动选择 Input Formatter。application/json
→ System.Text.Jsonapplication/xml
→ XmlSerializerapplication/x-www-form-urlencoded
→ Form 表单
-
-
注意:
- 一个 Action 只能有一个
[FromBody]
参数。 - 模型验证失败返回 400,可用
ApiController
特性自动包装ProblemDetails
。
- 一个 Action 只能有一个
2. 表单(Form)
- 在哪儿传 :
application/x-www-form-urlencoded
或multipart/form-data
(上传文件)。 - 怎么拿 :
-
简单:
csharp[HttpPost("login")] public IActionResult Login([FromForm] string username, [FromForm] string pwd) { ... }
-
复杂:绑定到 DTO。
csharppublic class ProfileDto { public string Name { get; set; } public IFormFile Avatar { get; set; } } [HttpPost("profile")] public async Task<IActionResult> UpdateProfile([FromForm] ProfileDto dto) { ... }
-
3. 路由 & 查询字符串 & 请求头
-
GET 里能用的,POST 一样能用:
csharp[HttpPost("devices/{deviceId}/command")] public IActionResult Command( [FromRoute] int deviceId, [FromQuery] string cmd, [FromHeader(Name = "X-Correlation-Id")] string cid, [FromBody] CommandPayload payload) { ... }
三、表格速查
传值位置 | 适用HTTP方法 | 绑定源 | 常见特性 / 参数写法 | 典型场景示例 |
---|---|---|---|---|
路由段 | GET/POST/... | [FromRoute] |
{id} |
RESTful 资源定位 |
查询字符串 | GET/POST/... | [FromQuery] |
?page=2&size=10 |
分页、过滤、排序 |
请求头 | GET/POST/... | [FromHeader] |
X-Api-Key |
鉴权、版本、链路追踪 |
请求体 (JSON) | POST/PUT/... | [FromBody] |
{ "name": "abc" } |
创建/更新复杂对象 |
表单字段 | POST/PUT/... | [FromForm] |
username=abc&pwd=123 |
传统网页表单、文件上传 |
服务注入 | 任意 | DI 容器 | 直接写在参数列表 | 日志、仓储、配置 |
四、常见坑 & 最佳实践
-
GET 请求不要带 Body
HTTP 规范未禁止,但部分客户端/代理会直接丢弃,导致调试困难。
-
复杂对象请统一用 DTO
避免 Action 参数过多,便于 Swagger/OpenAPI 自动生成文档。
-
同时用 query + body 时,注意模型绑定优先级
复杂类型默认
[FromBody]
,简单类型默认[FromQuery]
,如需覆盖手动标注。 -
文件上传
< 64 KB
自动缓存到内存;大文件需开启MultipartBodyLengthLimit
。- 用
IFormFile
/IFormFileCollection
接收。
-
模型验证
- 在 DTO 属性打
[Required]
、[Range]
等 DataAnnotations。 - 全局启用
options.SuppressModelStateInvalidFilter = false
(默认开启),让框架自动返回 400。
- 在 DTO 属性打
-
性能
- JSON 使用
System.Text.Json
,如需更快/更多特性可切换Newtonsoft.Json
。 - 关闭不必要的 XML formatter 减少启动开销。
- JSON 使用
五、最小可运行 Demo
Program.cs(.NET 6 minimal hosting model):
csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers(); // 启用 API 控制器
var app = builder.Build();
app.MapControllers();
app.Run();
Controllers/OrderController.cs:
csharp
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("[controller]")]
public class OrderController : ControllerBase
{
// GET /order/123?detail=full
[HttpGet("{id}")]
public IActionResult Get(int id, [FromQuery] bool detail = false)
=> Ok(new { id, detail });
// POST /order
[HttpPost]
public IActionResult Create([FromBody] CreateOrderDto dto)
=> CreatedAtAction(nameof(Get), new { id = 123 }, dto);
}
public class CreateOrderDto
{
public int ProductId { get; set; }
public int Quantity { get; set; }
}
至此,GET/POST 的所有主流传值方式、绑定方法及注意点已完整覆盖,可直接应用于日常开发与代码评审。
在 ASP.NET Core(包括 .NET 6/7/8)中,MultipartBodyLengthLimit
是用于限制 表单上传(multipart/form-data) 的最大字节数的配置项。默认值为 134,217,728
字节(约 128MB)。
✅ 如何开启或修改 MultipartBodyLengthLimit
✅ 方法一:在 Program.cs
中配置(推荐)
适用于 Kestrel 服务器(默认):
csharp
// 设置整个请求体的最大大小(可选)
builder.WebHost.ConfigureKestrel(options =>
{
options.Limits.MaxRequestBodySize = 100 * 1024 * 1024; // 100MB
});
// 设置 multipart 表单上传的最大大小
builder.Services.Configure<FormOptions>(options =>
{
options.MultipartBodyLengthLimit = 100 * 1024 * 1024; // 100MB
});
⚠️ 注意:
MaxRequestBodySize
必须大于或等于MultipartBodyLengthLimit
,否则仍然会报错。
✅ 方法二:针对单个接口设置(更灵活)
如果你只想对某个上传接口放宽限制,可以使用特性:
csharp
[HttpPost("upload")]
[RequestSizeLimit(100_000_000)] // 整个请求体最大 100MB
[RequestFormLimits(MultipartBodyLengthLimit = 100_000_000)] // 表单最大 100MB
public async Task<IActionResult> UploadFile(IFormFile file)
{
// 处理上传逻辑
return Ok();
}
✅ 方法三:关闭请求大小限制(慎用)
如果你希望完全关闭限制(不推荐用于生产):
csharp
[HttpPost("upload")]
[DisableRequestSizeLimit]
[RequestFormLimits(MultipartBodyLengthLimit = long.MaxValue)]
public async Task<IActionResult> UploadFile(IFormFile file)
{
return Ok();
}
⚠️ 注意事项
-
如果你部署在 IIS 后面,还需同步修改
web.config
中的:xml<system.webServer> <security> <requestFiltering> <requestLimits maxAllowedContentLength="104857600" /> <!-- 100MB --> </requestFiltering> </security> </system.webServer>
-
如果你使用 反向代理(如 Nginx),也需要设置:
nginxclient_max_body_size 100M;
✅ 总结速查表
配置项 | 默认值(字节) | 推荐设置位置 | 说明 |
---|---|---|---|
MaxRequestBodySize |
30,000,000 | ConfigureKestrel() |
整个请求体最大大小 |
MultipartBodyLengthLimit |
134,217,728 | Configure<FormOptions> |
multipart 表单最大大小 |
maxAllowedContentLength |
30,000,000 | web.config (IIS) |
IIS 层的请求体限制 |
如需上传大文件(如 >100MB),建议结合 流式处理 和 分片上传,避免内存溢出或超时问题。