在 ASP.NET Core MVC 中使用控制器处理请求Handle requests with controllers in ASP.NET Core MVC
本文内容
作者:Steve Smith 和 Scott Addie
控制器、操作和操作结果是开发人员如何使用 ASP.NET Core MVC 生成应用的一个基本组成部分。
什么是控制器?What is a Controller?
控制器用于对一组操作进行定义和分组。操作(或操作方法)是控制器上一种用来处理请求的方法。控制器按逻辑将类似的操作集合到一起。通过这种操作的聚合,可以共同应用路由、缓存和授权等通用规则集。请求通过路由映射到操作。
根据惯例,控制器类:
- 驻留在项目的根级别“Controllers”文件夹中。
- 继承自
Microsoft.AspNetCore.Mvc.Controller
。
控制器是一个可实例化的类,其中下列条件至少某一个为 true:
- 类名称带有
Controller
后缀。 - 该类继承自带有
Controller
后缀的类。 [Controller]
特性应用于该类。
控制器类不可含有关联的 [NonController]
属性。
控制器应遵循 Explicit Dependencies Principle(显式依赖关系原则)。以下几种方法可以实现此原则。如果多个控制器操作需要相同的服务,请考虑使用构造函数注入来请求这些依赖关系。如果该服务仅需要一个操作方法,请考虑使用操作注入来请求依赖关系。
在“模型-视图-控制器”模式中,控制器负责请求的初始处理和模型的实例化操作。通常情况下,应在模型中执行业务决策。
控制器获取模型处理的结果(如果有),并返回正确的视图及其关联的视图数据或 API 调用的结果。请参阅 ASP.NET Core MVC 概述以及 ASP.NET Core MVC 和 Visual Studio 入门了解详细信息。
控制器是一个 UI 级别的抽象。它的职责是确保请求的数据有效,并选择应当返回的视图(或 API 的结果)。在构造良好的应用程序中,它不会直接包括数据访问或业务逻辑。相反,控制器会委托给处理这些责任的服务。
定义操作Defining Actions
控制器上的公共方法(除了那些带有 [NonAction]
属性的方法)均为操作。操作上的参数会绑定到请求数据,并使用模型绑定进行验证。所有模型绑定的内容都会执行模型验证。ModelState.IsValid
属性值指示模型绑定和验证是否成功。
操作方法应包含用于将请求映射到某个业务关注点的逻辑。业务关注点通常应当表示为控制器通过依赖关系注入来访问的服务。然后,操作将业务操作的结果映射到应用程序状态。
操作可以返回任何内容,但是经常返回生成响应的 IActionResult
(或异步方法的 Task<IActionResult>
)的实例。操作方法负责选择响应的类型。操作结果会做出响应。
控制器帮助程序方法Controller Helper Methods
控制器通常继承自控制器(尽管没有要求)。派生自 Controller
会提供对三个帮助程序方法类别的访问:
1. 导致空响应正文的方法1. Methods resulting in an empty response body
没有包含 Content-Type
HTTP 响应标头,因为响应正文缺少要描述的内容。
该类别中有两种结果类型:重定向和 HTTP 状态代码。
- HTTP 状态代码
此类型返回 HTTP 状态代码。此类型的几种帮助程序方法是 BadRequest
、NotFound
和 Ok
。例如,return BadRequest();
执行时生成 400 状态代码。重载 BadRequest``NotFound
和 Ok
等方法时,它们不再符合 HTTP 状态代码响应方的资格,因为正在进行内容协商。
- 重定向
此类型(使用 Redirect
或 LocalRedirect
RedirectToActionRedirectToRoute
)返回一个到操作或目标的重定向。例如,return RedirectToAction("Complete", new {id = 123});
重定向到 Complete
,传递一个匿名对象。
重定向结果类型与 HTTP 状态代码类型的不同之处主要在于 Location
HTTP 响应标头的添加。
2. 导致具有预定义内容类型的非空响应正文的方法2. Methods resulting in a non-empty response body with a predefined content type
此类别中的大多数帮助程序方法都包含一个 ContentType
属性,通过它可以设置 Content-Type
响应标头来描述响应正文。
- 视图
此类型返回一个使用模型呈现 HTML 的视图。例如,return View(customer);
将模型传递给视图以进行数据绑定。
- 已格式化的响应
此类型返回 JSON 或类似的数据交换格式,从而以特定方式表示某个对象。例如,return Json(customer);
将提供的对象串行化为 JSON 格式。
此类型的其他常见方法包括 File
和 PhysicalFile
。例如,return PhysicalFile(customerFilePath, "text/xml");
返回 PhysicalFileResult。
3. 导致在与客户端协商的内容类型中设置非空响应正文的方法3. Methods resulting in a non-empty response body formatted in a content type negotiated with the client
此类别更为熟知的说法是“内容协商”。每当操作返回 ObjectResult 类型或除 IActionResult 实现之外的任何实现时,会应用内容协商。返回非 IActionResult
实现(例如 object
)的操作也会返回已格式化的响应。
此类型的一些帮助程序方法包括 BadRequest
、CreatedAtRoute
和 Ok
。这些方法的示例分别为 return BadRequest(modelState);
、return CreatedAtRoute("routename", values, newobject);
和 return Ok(value);
。请注意,BadRequest
和 Ok
仅在传递了值的时候才执行内容协商;在没有传递值的情况下,它们充当 HTTP 状态码结果类型。另一方面,CreatedAtRoute
方法始终执行内容协商,因为它的重载均要求传递一个值。
横切关注点Cross-Cutting Concerns
应用程序通常会共享其部分工作流程。示例包括需要身份验证才能访问购物车的应用,或者在某些页面上缓存数据的应用。要在某个操作方法之前或之后执行逻辑,请使用筛选器。对横切关注点使用筛选器可以减少重复。
可在控制器或操作级别上应用大多数筛选器属性(例如 [Authorize]
),具体取决于所需的粒度级别。
错误处理和响应缓存通常是横切关注点:
使用筛选器或自定义中间件可处理许多横切关注点。