ASP.NET Core 模型绑定

🍀介绍

在C#中,特别是在ASP.NET Core中,模型绑定是一个将HTTP请求中的数据映射到C#对象的过程。它使得开发者能够方便地从请求中提取数据,而无需手动解析请求体、查询字符串、路由数据等。ASP.NET Core提供了多种特性(Attributes)来指定模型绑定的来源。以下是一些常用的模型绑定特性及其区别:

[FromRoute]

  • 适用于:路由模板中的参数。
  • 描述:从路由模板中绑定数据到模型对象。
  • 示例:对于路由模板api/items/{id},你可以使用[FromRoute]来绑定id参数。

[FromQuery]

  • 适用于:查询字符串中的数据。
  • 描述:从URL的查询字符串中绑定数据到模型对象。
  • 示例:对于URL https://example.com/api/items?page=1&size=10,你可以使用[FromQuery]来绑定pagesize参数。

[FromHeader]

  • 适用于:HTTP请求头中的数据。
  • 描述:从HTTP请求头中绑定数据到模型对象或单个属性。
  • 示例:可以用来绑定如AuthorizationContent-Type等请求头。

[FromBody]

  • 适用于:POST、PUT等请求的请求体数据。
  • 描述:将请求体中的数据绑定到模型对象。通常用于JSON或XML格式的数据。
  • 注意事项:在一个动作方法中,通常只能有一个参数使用[FromBody],因为请求体只能被读取一次。

[FromForm]

  • 适用于:表单提交的数据。。
  • 描述:在ASP.NET Core Web API中,[FromForm]特性用于从HTTP请求的表单数据中绑定数据到模型对象。这通常用于处理multipart/form-data类型的请求,比如文件上传同时携带其他表单字段的场景。
  • 示例:假设你有一个Web API端点,用于接收用户上传的图片以及其他相关信息,你可以使用[FromForm]来绑定表单数据。

[FromServices]

  • 适用于:依赖注入的服务。
  • 描述:不是直接从请求中绑定数据,而是从依赖注入容器中获取服务实例。
  • 示例:常用于注入如ILoggerDbContext等服务。

[ModelBinder]

  • 适用于:自定义模型绑定逻辑。
  • 描述:允许你创建自定义的模型绑定逻辑。你可以通过实现IModelBinder接口或继承IModelBinderProvider来创建自定义的模型绑定器。

🍀演示

下面我们对上面提到的模型绑定特性对常用的几个进行使用演示

因为在Get请求中不能有body,因此我们先在get方法中演示前面三种模型绑定特性**[FromRoute]、[FromQuery] 和 [FromHeader]**。

简单来说 **[FromRoute]就是从数据路由中获取值,[FromQuery]从查询字符串中获取值,[FromHeader]**从HTTP标头中获取值

🐳**FromRoute、****FromQuery、**FromHeader

新建一个asp.net core项目,在controller中使用这三个标签

cs 复制代码
using Microsoft.AspNetCore.Mvc;

namespace testWebApi.Controller;

[ApiController]
[Route("api/[controller]")]
public class TestController:ControllerBase
{
    [HttpGet]
    [Route("Getoption/{id}")]
    public IActionResult Getoption([FromRoute]int id,[FromQuery] string query,[FromHeader] string header)
    {
        return Ok($@"route:{id},query:{query},header:{header}");
    }
}

启动项目,我们在swagger中请求测试一下

F12在网络请求情况中可以得知,route和query都在请求URL中,而header顾名思义,在我们的请求头中。

🐳FromForm

接下来我们在controller中增加一个post请求的方法,使用FromForm形似绑定数据

cs 复制代码
    [HttpPost]
    [Route("testForm")]
    public IActionResult TestForm([FromForm] int id, [FromForm] string name)
    {
        return Ok(@$"Id:{id}, Name:{name}");
    }

这里我们使用postman演示一下

🐤文件上传

FromForm我们通常用于文件上传,如下将参数类型改为IFormFile

cs 复制代码
    [HttpPost]
    [Route("upload")]
    public IActionResult UploadFile([FromBody] IFormFile file)
    {
        return Ok();
    }

在postman中上传文件测试一下,注意这里的key要和参数名(这里是 file)对应上

在file实例中我们可以看到他的文件名称,类型等信息。

🐳FromBody

要注意的是,在一个动作方法中,通常只能有一个参数使用[FromBody],因为请求体只能被读取一次。

cs 复制代码
    [HttpPost]
    [Route("testBody")]
    public IActionResult TestBody([FromBody] string name)
    {
        return Ok(name);
    }

post请求的方法体我们一般是使用json数据格式。

🐤对象模式绑定

因为请求体只能读取一次,要获取多个数据我们一般采用对象模式来进行模型绑定,首先创建一个Dto

cs 复制代码
public class Student
{
    public int Id { get; set; }
    
    public string? Name { get; set; }
}

然后在方法参数中将Dto设置为参数

cs 复制代码
    [HttpPost]
    [Route("testBody")]
    public IActionResult TestBody([FromBody] Student student)
    {
        return Ok(@$"Id:{student.Id}, Name:{student.Name}");
    }

请求测试!

注意我们的数据一定要遵守JSON数据的格式,如果对JSON数据格式不熟悉我们可以通过下面的在线JSON校验格式工具进行数据的检查。

在线JSON校验格式化工具(Be JSON)

事实上在上面说的的query,route,form,body,header这五种来源都可以使用这种对象现实来进行数据绑定,但是一般数据比较多的话我们通常选择将它放到post请求的body中

🐳模型验证

在使用对象模式进行模型绑定时,可以像如下通过一些标签来对我们要绑定的数据进行校验,如添加 [Required] 将这个参数设置为非空,然后 [Range(1,100)]设置我们的id取值只能在1-100之间,同时通过ErrorMessage(可选)来自定义我们的错误提示。

cs 复制代码
public class Student
{
    [Required]
    [Range(1,100,ErrorMessage = "只能传1-100的值!")]
    public int Id { get; set; }
    
    public string? Name { get; set; }
}

这些都是.netCore内置的验证特性,以下是一些内置验证特性:

关于更详细的其他内置验证特性,我们可以在官方文档中进行查阅👇

ASP.NET Core MVC 中的模型验证 | Microsoft Learn

相关推荐
monkey_meng40 分钟前
【Rust中的迭代器】
开发语言·后端·rust
余衫马43 分钟前
Rust-Trait 特征编程
开发语言·后端·rust
monkey_meng1 小时前
【Rust中多线程同步机制】
开发语言·redis·后端·rust
paopaokaka_luck5 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
码农小旋风7 小时前
详解K8S--声明式API
后端
Peter_chq7 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
Yaml47 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~7 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616887 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
睡觉谁叫~~~8 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust