当前位置: 首页 > news >正文

【ASP.NET Core】深入理解Controller的工作机制

系列文章目录

链接: 【ASP.NET Core】REST与RESTful详解,从理论到实现


文章目录

  • 系列文章目录
  • 前言
  • 一、Controller的泛用职责
  • 二、Controller的特性
    • 2.1 ApiController
    • 2.2 属性路由Route
    • 2.3 Action方法HTTP特性
    • 2.4 Action方法的异步实现
  • 三、Action方法参数
    • 3.1 URL占位符
    • 3.2 QueryString
    • 3.3 请求报文体
  • 四、Controller里的结果响应
    • 4.1 IActionResult
    • 4.2 ActionResult
  • 总结


前言

Web开发中,我们时刻都在和HTTP请求打交道,构建路由,解析请求,响应结果。在ASP.NET Core MVC/Web API中,有一个核心的组件,名为Controller。作为处理请求、协调模型和视图/响应的“指挥中心”。本文将深入探讨Controller的角色、功能。


一、Controller的泛用职责

Controller本质上是一个包含了Action方法的类,负责处理客户端HTTP请求,然后调用指定业务逻辑,最后再返回响应给客户端。可以把Controller简单的理解成请求的入口点(实际上Controller是连接着请求管道的末尾),通过路由映射,再匹配到到具体的Action调用逻辑。

我们可以把Controller的职责总结为三部分:

  • 处理客户端HTTP请求,映射路由,解析参数
  • 匹配具体Action,调用业务逻辑方法
  • 生成响应,返回客户端。

请求管道与控制器

实际上,作为一个完整的ASP.NET Core请求管道,严格来说Controller不属于请求管道本身,而Controller是这条管道最后抵达的“终点”。
Controller的目的是执行业务逻辑,它需要通过路由中间件和端点中间件与请求管道集成。在这个请求管道里,还有那些认证授权,记录日志等通用的中间件,抑或是限流等自定义中间件。事实上请求管道也就是由多个中间件组成的一条处理链

ASP.NET Core WebAPI里的Controller继承自ControllerBase;ASP.NET Core MVC里的Controller继承自Controller,其Controller内部也是继承自ControllerBase;:

  • ControllerBase是所有控制器的抽象基类,仅包含处理 HTTP 请求的核心功能,如状态码返回、模型验证、路由绑定等。
  • Controller继承自ControllerBase,并额外集成了视图引擎相关功能,用于处理需要返回视图。

二、Controller的特性

2.1 ApiController

ApiController是一个用于控制器的特性,主要是当传入的参数不符合数据模型验证,会自动返回400 Bad Request响应。

2.2 属性路由Route

控制器里的方法上通过标注Route自定义特性,来表示这个Controller包含的Action方法如何匹配。路由Route特性里可路由模板自定义路径。

[Route("api/[controller]")]GET方法 https://localhost:7027/api/[controller名称]

像类似"api/[controller]",模板里的[controller]是占位符。通过控制器的名称结合HTTP属性匹配Action方法。

https://localhost:7027/api/[controller名称]/[action名称]

也可也在模板里留下自定义action路径,通过控制器的名称和方法名称来匹配路由。

2.3 Action方法HTTP特性

  • [HttpGet]
  • [HttpGet(“{id}”)]
  • [HttpPost]
  • [HttpPut(“{id}”)]
  • [HttpPatch(“{id}”)]
  • [HttpDelete(“{id}”)]
    诸如以上几种方式,通过在Action前指定HTTP特性,便可通过不同的请求方式获取不同的Action。

2.4 Action方法的异步实现

使用async修饰Action,有返回值的通过Task包裹。Action的名称可不用Async尾缀修饰。

[HttpGet("{id}")]
public async Task<ActionResult<Student>> GetStudent(int id)

三、Action方法参数

3.1 URL占位符

在[HttpGet]、[HttpPost]等HTTP特性修饰的Action方法中使用占位符,来解析URL路径中的内容。
比如

[HttpGet("{id}")]
public ActionResult<Student> GetStudent(int id)
{var student = _students.FirstOrDefault(e => e.Id == id);if (student == null)return NotFound("");return Ok(student);
}

这个[HttpGet(“{id}”)]修饰的Action方法,就会解析URL里的匹配{id}占位符的内容,并且赋与GetStudent方法里的(int id)参数。

但是如果占位符的名字和方法里的参数名称不一致,可以用[FromRoute(Name=“名字”)]进行手动映射

[HttpGet("{idStr}")]
public ActionResult<Student> GetStudent([FromRoute(Name = "idStr")]string id)

3.2 QueryString

QueryString在请求路径是以?xxx=yyy&…的形式存在。如果Querystring中的名字和Action方法参数对应,那么框架会自动匹配。

[HttpGet]
public ActionResult<Student> GetStudent(int id)
{var student = _students.FirstOrDefault(e => e.Id == id);if (student == null)return NotFound("");return Ok(student);
}

但是如果占位符的名字和方法里的参数名称不一致,可以用[FromRoute(Name=“名字”)]进行手动映射

[HttpGet]
public ActionResult<Student> GetStudent([FromQuery(Name ="idStr")]string id)

3.3 请求报文体

一般HTTP的POST/PUT/PATCH请求中会用到报文体,一般通过[FromBody]绑定JSON数据(JSON格式的请求体是主流,客户端设定请求头中的Content-Type为application/json)。也有少部分通过表单提交数据[FromForm]。

存在URL占位符,QueryString和报文体嵌套的情况下,厘清Action方法里的数据参数对应的来源,用相应的诸如[FromRoute] [FromQuery] [FromBody]等修饰参数

四、Controller里的结果响应

在 ASP.NET Core WebAPI中,默认响应格式是JSON。当return Ok(data),框架会自动将对象序列化为JSON并设置响应头 Content-Type: application/json。
在返回格式上我们一般常用IActionResult 和 ActionResult。这样的好处是可以方便的调用框架里的各种封装好的方法,如各类状态码的返回。

4.1 IActionResult

IActionResult的使用在ASP.NET Core MVC中较为常见。这里的控制器的主要职责是返回视图,而非直接返回数据。
常见的诸如:
返回模型

 return View(model);

重定向

return RedirectToAction("Login", "Auth"); 

下载excel

return File(fileBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

这些都不是直接返回数据。MVC控制器的核心是视图渲染,以及混合这多种类型(视图、重定向、文件等)的返回。

4.2 ActionResult

Web API 通常返回单一类型的数据,并且考虑到格式,我们更加倾向于使用ActionResult的泛型ActionResult< T>返回数据对象,自动处理序列化和状态码。

[HttpGet("{id}")]
public ActionResult<Student> GetStudent(int id)
{var student = _students.FirstOrDefault(e => e.Id == id);if (student == null)return NotFound("");return student;
}

如上代码直接返回student,会被框架自动处理序列化和状态码。

这点我们观察泛型ActionResult< T>内部实现,它包含两个隐式的操作符转换。

  • 方法签名返回ActionResult< TValue>,但实际返回 TValue
  • 方法签名返回ActionResult< TValue>,但实际返回ActionResult result。

这两者都会触发new ActionResult< TValue>的执行。这样的好处是可以直接返回一个数据对象,或者一个ActionResult的方法。

如果没有隐式操作符

// 必须手动调用Ok()包裹示例
return Ok(classInstance);
// 必须手动包装
return new ActionResult<ClassName>(new NotFoundResult());

隐式操作符转换

/// <summary>
/// Implicitly converts the specified <paramref name="value"/> to an <see cref="ActionResult{TValue}"/>.
/// </summary>
/// <param name="value">The value to convert.</param>
public static implicit operator ActionResult<TValue>(TValue value)
{return new ActionResult<TValue>(value);
}/// <summary>
/// Implicitly converts the specified <paramref name="result"/> to an <see cref="ActionResult{TValue}"/>.
/// </summary>
/// <param name="result">The <see cref="ActionResult"/>.</param>
public static implicit operator ActionResult<TValue>(ActionResult result)
{return new ActionResult<TValue>(result);
}

总结

本文详解ASP.NET Core中Controller的职责、基类差异、特性、Action 参数绑定及响应方式,展现其处理HTTP 请求的核心作用。

http://www.dtcms.com/a/269889.html

相关文章:

  • Android T startingwindow使用总结
  • 【AI智能体】智能音视频-硬件设备基于 WebSocket 实现语音交互
  • ReactNative【实战系列教程】我的小红书 4 -- 首页(含顶栏tab切换,横向滚动频道,频道编辑弹窗,瀑布流布局列表等)
  • 深入解读MCP:构建低延迟、高吞吐量通信中间件
  • Terraform `for_each` 精讲:优雅地自动化多域名证书验证
  • ELK日志分析
  • Spring Boot 项目中的多数据源配置
  • Go语言网络游戏服务器模块化编程
  • C++——从C到C++
  • Mybatis-plus 中 LambdaQueryWrapper和QueryWrapper 区别对比,及完整示例演示
  • 大型语言模型(LLM)的最新研究进展及相关新信息技术
  • 如何在 Android Framework层面控制高通(Qualcomm)芯片的 CPU 和 GPU。
  • 在Docker中安装nexus3(作为maven私服)
  • 使用Node.js搭建Web应用有哪些注意事项?
  • 中韩SD-WAN网络加速专线:提升国内与韩国公司网络性能的关键
  • 四十四、NoSQL、Redis
  • Docker、Git与虚拟机:技术原理与深度对比(更新版)
  • 【网络安全】恶意 Python 包“psslib”仿冒 passlib,可导致 Windows 系统关闭
  • 【王树森推荐系统】召回12:曝光过滤 Bloom Filter
  • Java面试基础:概念
  • FairyGUI 实现 Boss 双层血条动画
  • 3D 演示动画在汽车培训与教育领域中的应用
  • 从0开始学习R语言--Day41--Moran‘s I
  • 城乡社区服务体系建设-城乡商城:意义深远与前景广阔——仙盟创梦IDE
  • 把文件夹下所有的excle写入word文件中
  • 50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | StickyNavbar(粘性导航栏)
  • Qwen视觉模型本地化部署,实现识别图片:Qwen2___5-VL-7B-Instruct
  • 分布式光纤传感:为储能安全保驾护航
  • 2025年7月:打cs1.5 600元装机台式电脑方案A
  • 学习软件测试的第十二天(接口测试)