在ASP.NET Core中,很多项目的结构都被简化了,一些约定也发生了细微的变化。目前大部分模板都是比较统一的,最简单的项目就是最近推出的Minimal API,其他的如MVC、Blazor都是在WebAPI的基础上拥有自己特有的东西。本文以WebAPI为例,介绍一下项目的基本结构。
如果不使用Minimal API的话,那么WebAPI项目依旧会有Controllers这个文件夹,即存放控制器代码的位置。控制器的说法来自于MVC时代,WebAPI项目是没有View和Model文件夹的,因为WebAPI是用于开发用HTTP(S) API的纯后端项目,本身并不含前端界面的设计。
除了Controllers文件夹,还有appsettings.json,这个文件作为项目的配置文件,一般用于发布阶段。它还包含一个子文件appsettings.Development.json,这个文件作为项目开发阶段使用的配置文件。
在.NET新版本中,已经没有Startup.cs这个文件,取而代之的是Program.cs文件,并且里面默认使用顶级语句:
var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
可以看出,在Program.cs里,WebAPI应用被创建、配置并运行。其中builder.Services用于注册依赖注入的各种服务,其中包括Controllers服务、Swagger服务。而builder.Build方法返回的app,可用于注册各种中间件,例如HTTPS重定向、权限验证、静态文件等。最后执行Run方法运行WebAPI。
在这里就必须理解什么是控制器、服务和中间件。
服务:这里的服务实际上是指依赖注入(DI)容器里的服务,在ASP.NET Core里,依赖注入系统是默认自带的,开发者可以在Program.cs里注册自己的服务,之后在每一个API请求中可以通过依赖注入来获取需要的服务。依赖注入的服务共有三种生命周期,特别地,在ASP.NET Core里,一般一个请求可视为一个Scope,无需自己创建。
控制器:WebAPI是纯粹的API设计,但依旧沿用MVC时代控制器的说法,本质上控制器就是用于接受API请求的模型。在WebAPI项目里,控制器继承自ControllerBase类,这个类是Controller类的基类,它去掉了一些WebAPI中没有用但可能在MVC中有用的功能,如果你需要使用MVC的一些支持,可以继承自Controller类。
在下面展示的示例代码中,有[ApiController]和[Route]两个特性,前者用于指明该类属于API控制器类,以便程序进行识别和Swagger读取。而Route用于指明该API控制器需要处理的HTTP(S)请求路径,即路由,在本例中,[controller]表示控制器名(不含Controller后缀)的占位符,即这个控制器将会接收到所有路径属于"/WeatherForecast"的请求。在控制器类中,每个公开的方法可用[HttpGet]、[HttpPost]、[HttpPut]等特性修饰,以便实现Rest风格的API。
using Microsoft.AspNetCore.Mvc; namespace ApiTest.Controllers { [ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; private readonly ILogger<WeatherForecastController> _logger; public WeatherForecastController(ILogger<WeatherForecastController> logger) { _logger = logger; } [HttpGet(Name = "GetWeatherForecast")] public IEnumerable<WeatherForecast> Get() { return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = Random.Shared.Next(-20, 55), Summary = Summaries[Random.Shared.Next(Summaries.Length)] }) .ToArray(); } } }
中间件:中间件是ASP.NET Core里对请求或者响应进行处理的模块,在一个请求到达之前,它会在所有中间件中过滤并可能被其中的某些进行处理,请求经过所有中间件后才到达控制器。
在请求结束后响应发出服务器之前,所有中间件也会对响应进行过滤和处理。中间件是ASP.NET Core的核心组件,MVC、Swagger、CORS都是内置中间件,所有的中间件组成一个管道,并且根据顺序(栈)依次执行逻辑。
在ASP.NET Core中,已经内置了Kestrel服务器,它实现了基本完整的、高效的HTTP(S)服务器功能,并且是适合跨平台的,这样WebAPI可以部署在任何平台,而不仅仅是Windows下IIS才能运行的了。