【.NET】WebAPI 项目结构

在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才能运行的了。