背景:.Net Core WebAPI 控制器中接收参数一般情况下分为简单类型(int、string、double....)、实体类dto、数据集合类型。
事实上,http请求可以把请求参数放到query、header、form、body中,而.net core WebAPI中默认启用了推理规则,可以自动推理参数在哪里并传入控制器参数中
| 特性 | 绑定源 |
|---|---|
| [FromBody] | 请求正文 |
| [FromForm] | 请求正文中的表单数据 |
| [FromHeader] | 请求标头 |
| [FromQuery] | 请求查询字符串参数 |
| [FromRoute] | 当前请求中的路由数据 |
| [FromServices] | 作为操作参数插入的请求服务 |
只是开启默认推理规则时,对于简单类型参数的接收,不能推理出去哪里接收,需要显示指定为[FromForm]或者[FromBody]
以下是默认规则下的接收参数方式:
////// 默认启用参数推理规则时 /// [Route("api/[controller]/[action]")] [ApiController] public class TestController : ControllerBase { [HttpPost] public ActionResult AddFormPara1([FromForm]string id) { //application/x-www-form-urlencoded //对于简单类型(string、int),推理不出来,所以需要显示指定参数来源FromForm var context = HttpContext.Request; return Ok(new { id = id }); } [HttpPost] public ActionResult AddFormPara([FromForm] string id, [FromForm] string name) { //application/x-www-form-urlencoded //对于简单类型(string、int),推理不出来,所以需要显示指定参数来源FromForm var context = HttpContext.Request; return Ok(new { id = id, name = name }); } [HttpPost] public IActionResult AddJsonPara1([FromBody] string id) { //json格式请求过来时Request中的data直接就是id的值,例:data:"111" var context = HttpContext.Request; return Ok(new { id = id }); } [HttpPost] public ActionResult AddJsonPara(dto dto) { //application/json {"id":"111","name":"winston"} var context = HttpContext.Request; return Ok(new { id = dto.id, name = dto.name }); } [HttpPost] public ActionResult AddJsonParaList(Listdto) { application/json [{"id":"111","name":"winston"}] var context = HttpContext.Request; return Ok(dto); } //[HttpPost] //public ActionResult AddJsonPara1([FromBody] string id, [FromBody] string name) //{ // //这种写法是不行的,FromBody只能指定一个参数 // var context = HttpContext.Request; // return Ok(new { id = id, name = name }); //} } public class dto { public string id { get; set; } public string name { get; set; } }
如果不想开启默认推理规则,即可以通过配置SuppressInferBindingSourcesForParameters来禁用
services.AddControllers(options =>
{
}).ConfigureApiBehaviorOptions(options =>
{
//options.SuppressConsumesConstraintForFormFileParameters = true;//禁用当[FromForm]属性批注时,推理multipart/form-data请求内容类型
options.SuppressInferBindingSourcesForParameters = true;//禁用api的推理规则,这样就支持post方式直接括号接受参数和model参数方式
});
禁用推理规则后,WebApi默认从form中取参,此时接参方式:
////// 禁用参数推理规则时 /// [ApiController] [Route("api/[controller]/[action]")] public class Test1Controller : ControllerBase { [HttpPost] public IActionResult AddFormPara1(string id) { //application/x-www-form-urlencoded //禁用推理规则后,application/x-www-form-urlencoded对于简单类型就不需要显示指定参数来源FromForm //但对于application/json的还是接不到 var context = HttpContext.Request; return Ok(new { id = id }); } [HttpPost] public IActionResult AddFormPara(string id,string name) { //application/x-www-form-urlencoded //禁用推理规则后,application/x-www-form-urlencoded对于简单类型就不需要显示指定参数来源FromForm //但对于application/json的还是接不到 var context = HttpContext.Request; return Ok(new { id = id, name = name }); } [HttpPost] public IActionResult AddJsonPara(dto1 dto) { //application/x-www-form-urlencoded //禁用推理规则后,依然可以用实体类来接收json格式数据,但前提是application/x-www-form-urlencoded var context = HttpContext.Request; return Ok(new { id = dto.id, name = dto.name }); } [HttpPost] public IActionResult AddListJsonPara([FromBody]Listdto) { //禁用推理规则后,对于json格式数据集合参数,需指定FromBody var context = HttpContext.Request; return Ok(dto); } } public class dto1 { public string id { get; set; } public string name { get; set; } }
总结:对于.Net Core WebAPI的默认推理规则,最好还是要开启,只是针对简单类型,需要显示指定FromBody或者FromForm,但是对于json格式参数和数据集合参数接收良好。



