ASP.NET Core-WebAPI

ASP.NET Core-WebAPI

Swagger

Swashbuckle 和 ASP.NET Core 入门 | Microsoft Learn

当我们创建好web API项目时,我们可以看到,项目默认存在一个软件包,其中就内置了Swagger的功能


Logging

ASP.NET Core 自带了一个日志记录框架,这个框架通过 Microsoft.Extensions.Logging 命名空间提供

这个命名空间包含了各种日志记录相关的接口和类,如 ILoggerILoggerFactory


DependencyInjection依赖注入

DI的依赖也被框架所包含

Microsoft.Extensions.DependencyInjection

在Action方法中,我们可以单独为某一个方法注入存在于DI中的依赖,而不通过构造函数的方式来注入服务

这种方式适用于某一个服务的执行过程很漫长,在构造函数中,对象实例化都会执行,所以不放在构造函数中

通过[FromService]特性,在Action方法的参数中实现注入

这样操作后,只有在调用此方法时才会将依赖实例化的对象注入,而不是在构造方法执行时就进行实例化注入


构造方法注入
private readonly ILogger<WeatherForecastController> _logger;

public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
    _logger = logger;
}

参数注入
[HttpGet]
public IActionResult GetWeatherForecast([FromServices] ILogger<WeatherForecastController> logger)
{	
    return Ok();
}

Program.cs

namespace WebAPI;

public class Program
{
    public static void Main(string[] args)
    {
        // 创建一个WebApplicationBuilder实例,用于配置应用程序。这个实例使用命令行参数初始化。
        var builder = WebApplication.CreateBuilder(args);

        // 注册MVC控制器服务,使应用程序能够处理HTTP请求。
        builder.Services.AddControllers();

        // 注册端点API探索器服务,用于生成API元数据,这些元数据可以被Swagger等工具使用。
        builder.Services.AddEndpointsApiExplorer();

        // 注册Swagger生成器服务,用于生成Swagger文档,这些文档可以用来生成API文档和交互式API测试界面。
        builder.Services.AddSwaggerGen();

        // 使用构建器创建一个配置好的WebApplication实例。
        var app = builder.Build();

        // 配置HTTP请求管道
        // 如果应用程序处于开发环境,则启用Swagger和Swagger UI
        if (app.Environment.IsDevelopment())
        {
            app.UseSwagger();  // 启用Swagger中间件,生成API文档
            app.UseSwaggerUI();  // 启用Swagger UI界面,提供交互式API测试
        }

        // 启用HTTPS重定向中间件,将所有HTTP请求重定向到HTTPS
        app.UseHttpsRedirection();

        // 启用授权中间件,处理授权逻辑,确保只有经过身份验证和授权的用户才能访问受保护的资源
        app.UseAuthorization();

        // 注册MVC控制器路由,告诉应用程序如何处理控制器中的路由
        app.MapControllers();

        // 启动应用程序,开始监听HTTP请求并处理它们
        app.Run();
    }
}

Controller

在Java中,一般返回值为集合时使用带泛型的List集合封装,但C#中使用IEnumerable进行封装

和MVC不同的是,WebAPI的Controller继承自ControllerBase,而不是Controller,因为Controller是基于ControllerBase增加了视图相关

using Microsoft.AspNetCore.Mvc;

namespace WebAPI.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;
    }

    // 在Java中,一般返回值为集合时使用带泛型的List集合封装,但C#中使用IEnumerable进行封装
    [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();
    }
}

特性(Attributes)解释

  1. [ApiController]

    • 含义[ApiController] 是一个特性,用于标记控制器类,表明该控制器是用于处理Web API请求的。这个特性会启用一些特定的行为,例如:
      • 模型验证:如果模型验证失败,会自动返回400 Bad Request响应。
      • 绑定源参数:自动处理绑定源参数,例如查询字符串、表单数据等。
      • 问题详细信息对象:在模型验证失败时,返回更详细的错误信息。
      • 异步支持:支持异步操作方法。
  2. [Route("[controller]")]

    • 含义[Route] 特性用于定义路由模板。[controller] 是一个占位符,会被替换为控制器的名称(去掉“Controller”后缀)。例如,WeatherForecastController 的路由路径将是 /weatherforecast
    • 用途:用于定义控制器的基路径,使得URL更加清晰和可预测。
  3. [HttpGet(Name = "GetWeatherForecast")]

    • 含义[HttpGet] 特性用于标记一个方法,表示该方法处理HTTP GET请求。Name 参数用于给该路由起一个名字,可以在其他地方引用这个路由。

    • 用途

      • HTTP动词:指定该方法只处理GET请求。
      • 命名路由:通过 Name 参数,可以在其他地方(如链接生成)引用这个路由

Swagger的500错误

当控制器存在一个没有特性修饰的public方法时,Swagger会报500错误

只需要将方法私有化,或者加上请求方式的特性修饰即可


Action方法

  • 无论是MVC还是WebAPI中,Action方法既可以是同步,也可以是异步(异步的Action方法一般不需要以Async结尾)

  • Action方法的返回值如果为引用类型,则会被默认序列化为JSON格式

  • Action方法的返回值也可以是IActionResult类型

  • 在WebAPI中,推荐使用IActionResult<>泛型方法,这个方法支持引用类型的序列化转换

注:IActionResult使用起来和在Java中我们自封装的Result结果集很相似,但返回方法由ControllerBase提供


请求参数

与Java相同,ASP.NET Core也有三种请求参数的方式

  • 路径参数
  • 键值对参数
  • 请求体参数

如果是请求体参数,则框架会自动帮忙结构并赋值到对象,不需要使用@RequestBody类似的注解

如果是路径参数,[FromRoute]特性与@PathVariable注解功能相同

如果是键值对参数,[FromQuery]特性与@RequestParam注解功能相同

如果是请求体参数,[FromBody]特性与@RequestBody注解功能相同

除了FromRoute、FromQuery、FromBody之外,还有FromForm、FromHeader等


WebAPI的请求风格

和SpringMVC相同,ASP.NET Core WebAPI也有两种请求风格:

  • RPC
  • REST

RPC

如果想强制实现RPC的URL风格,即让URL包含调用的具体方法名字,则需要在路由上加入action

这样在调用时,就需要使用控制器名/方法名的方式来调用方法

[ApiController]
[Route("[controller]/[action]")]
public class WeatherForecastController : ControllerBase
{
    ……
}

REST

具体实现流程和SpringMVC相同,具体可以翻看前面的笔记,需要注意的就是其特别的路径传参的方式

// PUT: api/WeatherForecast/5
// 路径传参方式
[HttpPut("{id}")]
public IActionResult Put(int id, WeatherForecast forecast)
{
    // 处理PUT请求,更新现有的WeatherForecast对象
    return NoContent();
}