ASP.NET Core学习笔记-3:Web API 基础、基础组件
本文最后更新于:2025年3月5日 晚上
第一个 Web API 项目!
项目结构
Controller
Web API 中的控制器类都继承自ControllerBase
类,并为其添加[ApiController]
这个Attribute
。示例代码中的另外一个[Route("[controller]")]
,用于设定路由规则,其中的[controller]
代表控制器的名字,也就是等于WeatherForecast
。
Restful
“幂等”操作:对于一个接口采用同样的参数请求一次和请求多次的结果是一致的,不会因多次请求而产生副作用。例如:发表评论成功,服务器返回结果给客户端,但是由于网络波动,客户端没能收到“发表成功”的返回结果,此时再次进行发表评论的操作,如果最终只发表了一次评论,那么这个操作就是幂等的;否则就不是。
Swagger
可以理解成提供了对应接口的文档的内置的 Postman(提供接口测试)。
注意:如果控制器中存在一个没有添加[HttpGet]
、[HttpPost]
等Attribute
的public
方法,Swagger 就会报错“Failed to load API definition”。解决办法:对应方法添加:[ApiExplorerSettings(IgnoreApi = true)]``Attribute
。
ActionResult
ActionResult<T>
通过隐式转换重载来完成BadRequest
、NotFound
等方法返回的非泛型的ActionResult
到ActionResult<T>
的转换,它也会完成具体值(比如某一实体类)到ActionResult<T>
的隐式转换。因此在操作方法中,我们可以直接:return new Book()
、return NotFound()
等。
操作方法的参数来源
URL
在[HttpGet]
、[HttpPost]
等Attribute
中使用占位符{ParameterName}
来捕捉路径中的内容:
1 |
|
QueryString
对于使用 QueryString 传递的参数,则是使用[FromQuery]
来获取值:
1 |
|
请求报文体
注意 Content-Type,在 Web API 开发中一般都是application/json
1 |
|
允许跨域
在 Program.cs 的var app = builder.Build();
前添加:
1 |
|
再在app.UseHttpsRedirection();
前添加:app.UseCors();
ASP.NET Core 基础组件
ASP.NET Core 中的依赖注入
在 Program.cs 中,WebApplication.CreateBuilder(args)
所返回的对象类型为WebApplicationBuilder
,它的Services
属性的类型则是IServiceCollection
,所以也拥有AddScoped()
等方法。一般把服务注册到这里就行。
食用指北
首先,创建一个服务类MyExampleService
,并随便实现一个方法:
1 |
|
然后,在 Program.cs 中注册服务:builder.Services.AddScoped<MyExampleService>();
最后,就可以在需要用到该服务的控制器的构造函数(Constructor)中注入服务啦:
1 |
|
但是有时候可能遇到特殊情况:如果一个操作方法(比如上面的Test()
就是一个操作方法)用到的服务(在上面的例子中,Test()
方法需要用到MyExampleService
服务)的注入比较消耗资源,而这个操作方法被调用到的频率又很低,那么在调用这个控制器中的其他方法时,又会重复注入这个服务,就很浪费资源。
为了避免这种情况,我们可以把调用方法所用到的服务,通过调用方法的参数来注入:
1 |
|
将配置系统集成到 ASP.NET Core 中
多环境设置
为了确定运行时环境,ASP.NET Core 会从环境变量中读取名字为ASPNETCORE_ENVIRONMENT
的值,这个值就是程序运行环境的名字。推荐采用如下3个值来:Development(开发环境)、Staging(测试环境)、Production(生产环境)。如果没有设置,则认为程序运行在生产环境。
我们可以分别为各个环境创建配置文件:appsettings.Development.json
、appsettings.Staging.json
、appsettings.Production.json
用“用户机密”来避免信息泄露
对应项目点击右键,选择“管理用户机密”,Visual Studio 会自动打开secrets.json
文件,在这个文件里就可以进行机密信息的配置了。
EF Core 与 ASP.NET Core 的集成
我们可能会将 EF Core 的项目与 ASP.NET 项目分开开发,以达到项目职责的清晰划分的目的,这个时候,我们如果要在 ASP.NET 用上下文,就需要用依赖注入的方式来配置数据库连接了,并添加对 EF Core 项目的依赖。
为了能在 ASP.NET 项目运行的时候再确定上下文对象需要连接到的数据库,我们需要修改一下上下文类:
1 |
|
可以看到现在的上下文类不再重写OnConfiguring
方法来设置数据库了,而是增加了一个MyDbContext(DbContextOptions<MyDbContext>)
类型参数的构造方法。DbContextOptions
是一个数据库连接配置对象,所以接下来,我们将在 ASP.NET 项目中(通过依赖注入的方法)提供对DbContextOptions
的配置:
1 |
|
别忘了在application.json
中配置连接字符串:
1 |
|
如果我们需要进行迁移,就需要为 EF Core 项目额外配置数据库连接。但是由于在 EF Core 项目中很难使用IConfiguration
来读取配置,所以我们可以通过添加系统环境变量来配置数据库连接字串,并在项目中添加一个实现IDesignTimeDbContextFactory
接口的实现类(数据库迁移工具会调用这个实现类的CreateDbContext
方法来获取上下文对象,并使用这个对象来连接数据库)来帮助进行迁移:
1 |
|
小上下文策略
“不要把项目中所有的实体类都放到同一个上下文类中,而是只把关系紧密的实体类放到同一个上下文类中…也就是项目中存在多个上下文类。”
批量注册上下文:
1 |
|
缓存
ASP.NET 不仅提供了把 Web 服务器的内存用作缓存的内存缓存(in-memory cache),还提供了把 Redis、数据库等用作缓存的分布式缓存(distributed cache)。
客户端响应缓存
cache-control
响应报文头能够控制浏览器对请求返回内容的缓存时间等,在 ASP.NET 中,我们可以手动控制这个响应报文头,如添加ResponseCacheAttribute
:
1 |
|
这样浏览器就会把相应内容缓存60s。
如果客户端不支持客户端缓存,那么这个设置不会生效。
服务器端响应缓存
如果在 ASP.NET Core 中安装了“响应缓存中间件”(response cache middleware),那么设置[ResponseCache]
不仅会设置客户端缓存,还会设置服务端缓存。
希望本文章能够帮到您~