Asp.net core 模型绑定

ASP.NET Core 中,模型绑定(Model Binding)是将 HTTP 请求中的数据(如路由参数、查询字符串、请求体等)自动映射到控制器 Action 方法参数的过程。

当多个数据源中存在同名参数时,框架会按照一个固定的优先级顺序来决定使用哪个值。

📋 默认绑定源优先级

ASP.NET Core 的模型绑定器会按照以下顺序依次查找数据,并使用第一个找到的值

  1. 表单值 (Form values)
    • 来自 application/x-www-form-urlencodedmultipart/form-data 请求的表单字段。
  2. 路由值 (Route values)
    • 来自 URL 路由模板中定义的参数(例如 /api/products/{id} 中的 id)。
  3. 查询字符串 (Query string)
    • 来自 URL 中 ? 后面的键值对(例如 /api/products?id=5)。
  4. 请求体 (Request body)
    • 来自 application/jsonapplication/xml 等格式的请求体内容。
    • 特别注意:对于复杂类型(如自定义的类对象),默认情况下会从请求体中绑定。

核心规则:一旦在某个源中找到了匹配的参数名,绑定过程就会停止,后续优先级较低的源中即使有同名参数也会被忽略。

💻 代码示例

假设有以下控制器和 Action:

csharp 复制代码
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    // GET /api/products/5?price=100
    [HttpGet("{id}")]
    public IActionResult GetProduct(int id, int price)
    {
        // 此时 id = 5 (来自路由), price = 100 (来自查询字符串)
        return Ok(new { Id = id, Price = price });
    }
}

现在,我们通过一个 POST 请求来演示优先级冲突:

请求:

http 复制代码
POST /api/products/99?price=50
Content-Type: application/x-www-form-urlencoded

price=200&id=88

模型绑定结果:

  • id 参数:
    1. 首先在表单值 中查找,找到 id=88
    2. 绑定成功,id 的值为 88。路由中的 99 被忽略。
  • price 参数:
    1. 首先在表单值 中查找,找到 price=200
    2. 绑定成功,price 的值为 200。查询字符串中的 50 被忽略。

最终,Action 方法接收到的参数是 id=88price=200

🛠️ 使用特性控制绑定源

你可以使用 [From...] 系列特性来显式指定参数的绑定源,这会覆盖默认的优先级规则。

特性 说明
[FromForm] 强制从表单值中绑定。
[FromRoute] 强制从路由值中绑定。
[FromQuery] 强制从查询字符串中绑定。
[FromBody] 强制从请求体中绑定。
[FromHeader] 从请求头中绑定。
[FromServices] 从依赖注入容器中解析服务。

示例:

csharp 复制代码
// GET /api/products/5?price=100
[HttpGet("{id}")]
public IActionResult GetProduct(
    [FromRoute] int id,       // 明确指定从路由绑定
    [FromQuery] int price)    // 明确指定从查询字符串绑定
{
    // ...
}

在这种情况下,即使请求中包含同名的表单字段,idprice 也只会从指定的源(路由和查询字符串)获取值。如果指定的源中不存在该参数,则会绑定失败(对于非可空类型会报错)。

相关推荐
有梦不弃4 小时前
模块化单体架构设计方案:DDD + 六边形架构落地实践
后端·架构
江南十四行8 小时前
Spring框架核心(上)——IoC控制反转与DI依赖注入详解
java·后端·spring
IT_陈寒9 小时前
Redis缓存击穿把我坑惨了,原来这样设过期时间才靠谱
前端·人工智能·后端
妙码生花10 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(五十二):管理员权限检查中间件,AI 随意放行预闯大祸
前端·后端·go
创安电气研究所10 小时前
用 Node.js 将变频器运行数据接入 MQTT
后端
董员外10 小时前
RAG 系统进化论(八):Agentic RAG(智能体式 RAG),从回答问题到完成任务
人工智能·后端·设计模式
大勇前进10 小时前
告别 div 满天飞,HTML5 语义化标签真的有必要用吗?
后端
小满zs10 小时前
Go语言第六章(结构体)
后端·go
属于自己的天空10 小时前
每天省去重复 Prompt:我用 Skills 把 CRUD 生成标准化了
前端·后端