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
命名空间提供
这个命名空间包含了各种日志记录相关的接口和类,如 ILogger
和 ILoggerFactory
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)解释
-
[ApiController]
- 含义:
[ApiController]
是一个特性,用于标记控制器类,表明该控制器是用于处理Web API请求的。这个特性会启用一些特定的行为,例如:- 模型验证:如果模型验证失败,会自动返回400 Bad Request响应。
- 绑定源参数:自动处理绑定源参数,例如查询字符串、表单数据等。
- 问题详细信息对象:在模型验证失败时,返回更详细的错误信息。
- 异步支持:支持异步操作方法。
- 含义:
-
[Route("[controller]")]
- 含义:
[Route]
特性用于定义路由模板。[controller]
是一个占位符,会被替换为控制器的名称(去掉“Controller”后缀)。例如,WeatherForecastController
的路由路径将是/weatherforecast
。 - 用途:用于定义控制器的基路径,使得URL更加清晰和可预测。
- 含义:
-
[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();
}