3.2 控制器 (Controller) 3.2 控制器 (Controller) in ASP.NET Core MVC 在 ASP.NET Core MVC 架构中,控制器 (Controller) 扮演着至关重要的角色,它负责接收来自客户端的请求,处理这些请求,并返回响应。简单来说,控制器是连接模型 (Model) 和视图 (View) 的桥梁,它协调数据的获取、业务逻辑的执行,以及最终用户界面的呈现。 3.2.1 控制器的职责 一个典型的控制器负责以下职责: 接收请求: 接收来自路由系统的 HTTP 请求(例如 GET, POST, PUT, DELETE)。 处理请求: 根据请求的类型和参数,执行相应的业务逻辑。这可能涉及到从数据库中检索数据、验证用户输入、调用服务层等。
在 ASP.NET Core MVC 架构中,控制器 (Controller) 扮演着至关重要的角色,它负责接收来自客户端的请求,处理这些请求,并返回响应。简单来说,控制器是连接模型 (Model) 和视图 (View) 的桥梁,它协调数据的获取、业务逻辑的执行,以及最终用户界面的呈现。
一个典型的控制器负责以下职责:
接收请求: 接收来自路由系统的 HTTP 请求(例如 GET, POST, PUT, DELETE)。
处理请求: 根据请求的类型和参数,执行相应的业务逻辑。这可能涉及到从数据库中检索数据、验证用户输入、调用服务层等。
准备数据: 将处理结果转换为适合视图展示的数据模型。
返回响应: 根据请求的结果,返回合适的 HTTP 响应。这可以是 HTML 视图、JSON 数据、重定向等。
在 ASP.NET Core MVC 中,控制器通常是一个继承自 ControllerBase 或 Controller 类的 C# 类。Controller 类继承自 ControllerBase,并添加了对视图的支持。
3.2.2.1 使用 Controller 类 (推荐):
using Microsoft.AspNetCore.Mvc; namespace MyWebApp.Controllers { public class HomeController : Controller { public IActionResult Index() { return View(); } public IActionResult Privacy() { return View(); } } }
在这个例子中,HomeController 继承自 Controller 类。 Index 和 Privacy 是 Action 方法,它们处理对 /Home/Index 和 /Home/Privacy 的请求。 View() 方法用于返回一个视图。
3.2.2.2 使用 ControllerBase 类 (API 控制器):
如果你的控制器主要用于返回 API 响应 (例如 JSON),那么可以继承自 ControllerBase 类。
using Microsoft.AspNetCore.Mvc; namespace MyWebApp.Controllers { [ApiController] [Route("api/[controller]")] public class ProductsController : ControllerBase { [HttpGet] public ActionResult<IEnumerable<string>> Get() { return new string[] { "value1", "value2" }; } } }
在这个例子中,ProductsController 继承自 ControllerBase 类,并且使用了 [ApiController] 和 [Route] 特性来定义 API 路由。 Get() 方法返回一个字符串数组。
Action 方法是控制器中负责处理特定请求的公共方法。 它们通常返回一个 IActionResult 类型的对象,该对象代表 HTTP 响应。
3.2.3.1 IActionResult 类型
IActionResult 是一个接口,它定义了 Action 方法必须实现的契约。 ASP.NET Core MVC 提供了多种 IActionResult 的实现,用于返回不同类型的响应:
ViewResult: 返回一个视图。
JsonResult: 返回 JSON 数据。
ContentResult: 返回文本内容。
RedirectResult: 重定向到另一个 URL。
FileResult: 返回一个文件。
StatusCodeResult: 返回一个指定的状态码。
OkResult: 返回200 OK状态码.
BadRequestResult: 返回400 Bad Request状态码.
NotFoundResult: 返回404 Not Found状态码.
3.2.3.2 Action 方法参数
Action 方法可以接受参数,这些参数可以从以下来源获取:
路由数据: 从 URL 路由中提取的参数。
查询字符串: 从 URL 查询字符串中提取的参数。
表单数据: 从 POST 请求的表单数据中提取的参数。
请求体: 从请求体中提取的参数 (例如 JSON 或 XML 数据)。
绑定模型: 使用模型绑定器将请求数据绑定到 C# 对象。
代码示例:
using Microsoft.AspNetCore.Mvc; namespace MyWebApp.Controllers { public class ProductsController : Controller { // 从路由数据获取 id public IActionResult Details(int id) { // 根据 id 获取产品信息 var product = GetProductById(id); if (product == null) { return NotFound(); // 返回 404 状态码 } return View(product); // 将产品信息传递给视图 } // 从查询字符串获取 category 和 page public IActionResult List(string category, int page = 1) { // 根据 category 和 page 获取产品列表 var products = GetProductsByCategoryAndPage(category, page); return View(products); } // 从表单数据获取数据 [HttpPost] public IActionResult Create(Product product) // 使用模型绑定器 { if (ModelState.IsValid) { // 保存产品信息 SaveProduct(product); return RedirectToAction("Index"); // 重定向到 Index action } return View(product); // 返回视图,显示验证错误 } private Product GetProductById(int id) { // 模拟从数据库获取产品信息 if (id == 1) { return new Product { Id = 1, Name = "Product 1", Price = 10 }; } return null; } private List<Product> GetProductsByCategoryAndPage(string category, int page) { // 模拟从数据库获取产品列表 List<Product> products = new List<Product>(); for (int i = 0; i < 5; i++) { products.Add(new Product { Id = i + 1, Name = $"{category} Product {i + 1}", Price = 20 + i }); } return products; } private void SaveProduct(Product product) { // 模拟保存产品到数据库 Console.WriteLine($"Saving product: {product.Name}"); } } public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } } }
路由是将传入的 HTTP 请求映射到特定控制器的 Action 方法的过程。 ASP.NET Core MVC 使用路由中间件来处理路由。
3.2.4.1 约定路由 (Convention-based Routing)
约定路由是最常见的路由方式。 它使用预定义的路由模板来匹配 URL。 在 Startup.cs 文件中,你可以配置约定路由:
app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); });
这个路由模板定义了以下约定:
{controller}: 控制器名称。
{action}: Action 方法名称。
{id?}: 可选的 ID 参数。
例如,URL /Products/Details/123 将被映射到 ProductsController 的 Details Action 方法,并将 id 参数设置为 123。
3.2.4.2 特性路由 (Attribute Routing)
特性路由允许你在控制器和 Action 方法上使用特性来定义路由。 这种方式更加灵活,可以创建更复杂的路由规则。
using Microsoft.AspNetCore.Mvc; namespace MyWebApp.Controllers { [Route("api/[controller]")] // 定义控制器的路由前缀 [ApiController] public class BooksController : ControllerBase { [HttpGet] // 匹配 GET 请求 public ActionResult<IEnumerable<string>> GetAll() { return new string[] { "Book1", "Book2" }; } [HttpGet("{id}")] // 匹配 GET 请求,并获取 id 参数 public ActionResult<string> GetById(int id) { return "Book " + id; } } }
在这个例子中,[Route("api/[controller]")] 特性定义了控制器的路由前缀为 api/Books。 [HttpGet] 特性定义了 GetAll Action 方法处理 GET 请求, [HttpGet("{id}")] 特性定义了 GetById Action 方法处理 GET 请求,并从 URL 中获取 id 参数。
模型绑定是将 HTTP 请求数据绑定到 C# 对象的过程。 ASP.NET Core MVC 提供了强大的模型绑定器,可以自动将请求数据转换为 Action 方法的参数。
3.2.5.1 简单类型绑定
模型绑定器可以自动将请求数据绑定到简单类型 (例如 int, string, bool, DateTime) 的参数。
3.2.5.2 复杂类型绑定
模型绑定器还可以将请求数据绑定到复杂类型的对象。 它会根据请求数据的名称和对象的属性名称进行匹配。
3.2.5.3 自定义模型绑定器
如果需要更高级的绑定逻辑,你可以创建自定义的模型绑定器。
模型验证是验证绑定到模型的数据的过程。 ASP.NET Core MVC 提供了多种验证方式,包括数据注解验证和自定义验证。
3.2.6.1 数据注解验证
数据注解验证使用 System.ComponentModel.DataAnnotations 命名空间中的特性来定义验证规则。
using System.ComponentModel.DataAnnotations; namespace MyWebApp.Models { public class User { [Required(ErrorMessage = "用户名不能为空")] [StringLength(50, MinimumLength = 3, ErrorMessage = "用户名长度必须在 3 到 50 个字符之间")] public string Username { get; set; } [EmailAddress(ErrorMessage = "邮箱格式不正确")] public string Email { get; set; } [Range(18, 60, ErrorMessage = "年龄必须在 18 到 60 之间")] public int Age { get; set; } } }
3.2.6.2 自定义验证
你可以创建自定义的验证属性或实现 IValidatableObject 接口来实现自定义验证逻辑。
ASP.NET Core MVC 控制器是短暂的,它们在处理每个请求时被创建,并在请求处理完成后被销毁。 依赖注入容器负责创建控制器实例,并注入所需的依赖项。
图例:
Client Request: 客户端发起的 HTTP 请求。
Routing: 路由系统将请求映射到特定的控制器和 Action 方法。
Controller Factory: 负责创建控制器实例。
Controller Instance: 控制器实例,包含 Action 方法。
Action Method: 处理请求的 Action 方法。
Model Binding: 将请求数据绑定到模型。
Model Validation: 验证模型数据的有效性。
Business Logic: 执行业务逻辑。
Prepare Data: 准备要返回的数据。
IActionResult: Action 方法返回的 HTTP 响应。
Response: 最终返回给客户端的 HTTP 响应。
控制器是 ASP.NET Core MVC 架构的核心组件,它负责接收请求、处理请求、准备数据和返回响应。 理解控制器的职责、Action 方法、路由、模型绑定和模型验证对于开发健壮的 ASP.NET Core MVC 应用程序至关重要。 通过合理的设计和使用控制器,可以构建清晰、可维护和可测试的 Web 应用程序。