本文内容来自书籍: Marinko Spasojevic - Ultimate ASP.NET Core Web API - From Zero To Six-Figure Backend Developer (2nd edition)
applicationUrl
/launchUrl
与.NET 5相比较,这个文件的变化在
global using
指令,如果不需要隐式指令,可以在.csproj文件中配置关闭<ImplicitUsings>disable</ImplicitUsings>
Startup
文件的ConfigureServices
和Configure
配置,已经在全部合并在Program.cs
中var builder = WebApplication.CreateBuilder(args);
这个builder的类型是WebApplicationBuilder
,然后这个类主要负责
builder.Configuration
添加项目配置builder.Services
注册服务builder.Logging
配置日志系统IHostBuilder
和IWebHostBuilder
的配置var builder = WebApplication.CreateBuilder(args); // 注册服务 var app = builder.Build(); // 注册中间件
在注册服务的时候,往往会有很多配置,那么为了让Program.cs
这个文件看起来比较整洁,我们可以给WebApplicationBuilder
编写扩展方法,来替代直接写在Program.cs
的配置
然后是写一个跨域配置为例子(一般我会用Nginx来解决跨域)
首先是创建一个静态类用以编写扩展方法
Extensions/ServiceExtensions.cs
然后在里面注册服务
// Extensions/ServiceExtensions.cs public static class ServiceExtensions { public static void ConfigureCors(this IServiceCollection service) => service.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader()); }); }
WithOrigins()
方法来指定主机地址,使用WithMethods()
指定HTTP方法,`WithHeaders()指定请求头AddControllers()
,它只会将Controller注册到IServiceCollection
中,而没有Views或者Pages,因为在WebAPI中不需要
var app = builder.Build();
在这个方法之后,我们得到了WebApplication
,这个类非常重要,因为它实现很多接口:
IHost
,开启,关闭主机IApplicationBuilder
,用来构建中间件管道IEndpointRouteBuilder
,用来添加端点到我们的app中UseHttpRedirection()
方法,添加一个中间件用来将HTTP转发到HTTPS中
UseAuthorization()
方法,添加一个中间件用来授权
MapControllers()
方法,添加来自controller actions的endpoints到IEndpointRouteBuilder
Run()
方法,启动应用并阻塞直到Host关闭
微软官网提示,添加中间件的顺序很重要
需要区分development
和production
环境变量,因为在不同环境,它们的地址、端口、密码、数据库等都不一样
所以我们需要将它们分割开,所以就有了项目创建时的两个配置文件
appsettings.json
appsetings.Development.json
(这里的配置会覆盖上面那个文件的配置)appsettings.{EnvironmentSuffix}.json
文件会把appsettings.json
的配置覆盖
通过ASPNETCORE_ENVIRONMENT
这个环境变量来设置使用哪一个配置文件
其实中间件可以认为是一个代码区域环绕在requests
和responses
外围
然后按照注册的顺序,不断调用next
方法向下传递,直到一个中间件不再调用即终点
添加自定义的中间件,有两种:
Run
:没有next
方法,它总是终点,这个方法接受一个RequestDelegate
类型的委托,这个委托的入参是HttpContext
,它里面包含着requests
和responses
,然后可以通过修改它们来达到我们的目的Use
:链接多个中间件,它接受Func
委托,两个入参,一个出参,第二个Func
是到达下个中间件的方法public static IApplicationBuilder Use(this IApplicationBuilder app,Func<HttpContext, Func<Task>, Task> middleware);
不能在Use中,写入了
responses
然后继续调用next
,这样会报错
Map
:作为管道的分支,请求经过这里的时候,会匹配路径,如果正确,会走向这个分支的中间件管道public static IApplicationBuilder Map(this IApplicationBuilder app,PathString pathMatch, Action<IApplicationBuilder> configuration)
MapWhen
:也是管道分支,不过不是使用路径匹配,而是一个predicate
判断是否进入public static IApplicationBuilder MapWhen(this IApplicationBuilder app, Func<HttpContext, bool> predicate, Action<IApplicationBuilder> configuration)