Intern Day7 - ASP.Net Core中间件的创建
按照约定来创建:
-
具有类型为RequestDelegate(是一个请求委托 )的参数的公共构造函数
-
名为Invoke或InvokeAsync的公共方法,这个方法必须满足两个条件
-
返回Task
-
接受类型HttpContext的第一个参数
-
TestMiddleware.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
/*
按照约定来创建中间件:
1. 具有类型为RequestDelegate(是一个请求委托 )的参数的公共构造函数
2. 名为Invoke或InvokeAsync的公共方法,这个方法必须满足两个条件
1. 返回Task
2. 接受类型HttpContext的第一个参数
*/
namespace WebApplication3
{
public class TestMiddleware
{
private readonly RequestDelegate _next; // 2、把next放到当前类的私有字段里,没有这个下面没法调用
public TestMiddleware(RequestDelegate next) // 1、首先要有一个构造函数和参数,next指向的就是下一个中间件
{
_next = next;
}
// 因为异步,所以需要加上async这个关键字。返回值是Task。名字是InvokeAsyn。后面是参数
// 中间件的功能代码就是写里面的,支持方法注入
// 只有中间件所依赖的类,才需要注册到容器里
// 如果这个中间件还需要依赖其他的类,那么写成:
// public async Task InvokeAsync(HttpContext httpContext,IConfiguration configuration)
public async Task InvokeAsync(HttpContext httpContext) // 这一部分就是一个简单的中间件
{
// 输出当前httpContext里面的请求路径,没有东西的话直接就是 message:/
await httpContext.Response.WriteAsync($"Message:{httpContext.Request.Path}");
// 这里选择是否调用next,如果不调用的话,那么这个中间件会触发短路,就是一个终端中间件了
//如果选择调用的话,这里的next是一个委托,这个委托需要一个参数就是httpContext
await _next(httpContext);
}
// 创建好的中间件如何使用(即如何添加到管道中去)(见Startup.cs)
/*
运行之后会显示:
Middleware 1 Begin
Middleware 2 Begin
Message:/swaggerHello Run
Middleware 2 End
Middleware 1 End
*/
}
}
Startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using WebApplication3.Model;
namespace WebApplication3
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
// IConfiguration 程序配置接口,用来读取文件和内存中的配置
public IConfiguration Configuration { get; }
// 这个方法用于处理中间件/配置服务,在时候被执行
// IServiceCollection服务配置接口,用来配置常用服务及依赖注入
public void ConfigureServices(IServiceCollection services) // 注入
{
// 添加
services.AddDbContext<TodoContext>(options => options.UseInMemoryDatabase("tododb"));
// service这个容器里面注入dbcontext,传入一个 tododb 字符串
//MemoryDatabase内存数据库:微软通过内存模拟了一个secseray,允许dbcontext访问,可以更换成pgsql等,这行代码表示可以往这个数据库里添加数据
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo {Title = "WebApplication3", Version = "v1"});
});
}
// IApplicationBuilder应用配置接口,用来配置中间件,所有的中间件都写在这个下面
// IWebHostEnvironment主机环境,用于不同环境不同处理
// 中间件本质其实就是一堆委托
// 我们不会在这里直接use、run使用他们,这里使用是为了方便理解
// 这个方法仅仅用来注册中间件,只会执行一次,主机run的时候执行,执行的目的是把以下中间件添加到管道里
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// 第一个泛型参数是传入的,第二个是返回值类型next(指向的是管道中的下一个中间件)
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("Middleware 1 Begin\n"); // 请求处理
await next(); // 指向了下一个中间件 (可以理解为把中间件串起来),就是一个异步委托
// use和run都向管道里添加了一个中间件。
// 如果没有这句话,相当于直接终结了,管道会短路,那么run不会执行了
await context.Response.WriteAsync("Middleware 1 End\n");//响应
});
app.Use(async (context, next) => //如果不用到next的话,next部分可以用 _ 代替
{
await context.Response.WriteAsync("Middleware 2 Begin\n");
await next();
await context.Response.WriteAsync("Middleware 2 End\n");
});
// 注册自定义中间件:我们可以自己写一个类,这个类就是中间件类。并且还为我们的中间件类提供了依赖注册的功能
// 最简单的方法 <> 泛型里写中间件TestMiddleware
app.UseMiddleware<TestMiddleware>(); // 后面要写run,因为没有终端中间件会报错
// 添加一个终端/终结点中间件中间件委托到管道,()里面接受的是一个委托,这个委托就是我们的中间
// 但是一般不会这么写
app.Run(async context => //默认直接返回,回去的时候进行响应操作
//注意:响应是响应,返回是返回
{
await context.Response.WriteAsync("Hello Run\n");
//在委托里写,调用上下文对象进行响应
// 因为这边直接响应了,所以下面的就不会再执行了
});
//这个中间件只做了一件事:在我们的响应里写上 Hello Run 这句话
/*
以上三个中间件执行完后输出:
Middleware 1 Begin
Middleware 2 Begin
Middleware 2 End
Middleware 1 End
*/
//以下都是默认的
//第一个中间件
//这个方法用于处理HTTP请求的管道(如路由等)
}
// if (env.IsDevelopment()) // 判断是不是一个开发模式
// {
// app.UseDeveloperExceptionPage();//提供了一个开发人员异常页面(即捕捉异常的代码在最前面)
// app.UseSwagger();
// app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApplication3 v1"));
// } // 可以放在方法开头
//
// app.UseHttpsRedirection();
//
// app.UseRouting(); // 路由中间件
//
// app.UseAuthorization();
//
// // 终端中间件
// app.UseEndpoints(endpoints =>
// {
// endpoints.MapControllers();
// });
}
}
参考
参考视频:https://www.bilibili.com/video/BV1r7411A7Z2?from=search&seid=9070934629069273158
参考博客(这个需要的时候可以看一下):https://www.cnblogs.com/jackyfei/p/9939352.html
分类:
.NET后端开发
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」