目录:

1、Core 处理HTTP请求流程

2、中间件(Middleware)&&处理流程

3、创建自定义中间件&&模拟Core的请求管道

Core 处理HTTP请求流程

Http请求来到之后,会先由WebServer( 例如IIS,Nginx) 拿到然后丢给Kestrel WebServer,再有Kestrel 将Http请求封装为HttpContext后传入给.net core 请求管道(RequestDelegate)。HttpContext经过一系列middleware后返回response给WebServer。

中间件(Middleware)&&处理流程

  微软官方文档给出的解释是这样的:中间件是加载在应用程序管道中以处理和相应请求的组件。其中每个组件都可以 选择是否可以将请求传递给管道中下一个组件;可以在调用管道的下一个组件之前或之后执行。下面是官方文档给出的一张图。

  也就是说一个http请求的处理过程为,经过中间件1的处理逻辑(这个时候可以在中间件1中对httpcontext做一些处理,例如写入一段内容),调用next()方法,进入到中间件2中,重复以上步骤。最终,所有中间件的处理逻辑的输出结果都会叠加到HttpResponse中去。

  .net core 中有三种方式调用中间件。在StartUp的Configure方法中,分别可以调用app.Use(),app.Run(),app.Map() 来调用中间件。接下来让我们来看下:

  app.Use方法有两个重载形式:

第一个方法接收一个中间件,第二个方法接收一个上下文和一个中间件。让我们来分别调用下:

             app.Use(next =>
{
return context =>
{
context.Response.WriteAsync("this is middleware1 start... ");
return next(context);
};
});
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("this is middleware2 start... ");
await next();
});

  app.Run方法会终止管道,返回HttpResponse。在我们Configure方法中,默认最后一个方法就是app.Run 输出一句HelloWorld ,如下图

  Use和Run都比较简单,不再详细介绍了。来看一眼程序运行结果:

  app.Map 方法用来构建分支管线,它会启用一个新的ApplicationBuilder。Map根据请求的路径来匹配分支管线。Map方法也可以根据不同的PathString来匹配多个分支管线或嵌套匹配。

            app.Map("/task", build =>
{
build.Run(async (context) =>
{
await context.Response.WriteAsync("this is middleware3 For Map start... ");
});
});
             app.Map("/map", build =>
{
build.Map("/mapTest2", MapHandleTest2);
build.Run(async (context) =>
{
await context.Response.WriteAsync("this is middleware3 For Map start... ");
});
});
app.Map("/mapTest1", MapHandleTest1);
         private void MapHandleTest1(IApplicationBuilder applicationBuilder)
{
applicationBuilder.Run(async context =>
{
await context.Response.WriteAsync("this is middleware3HandleTest1 For Map start... ");
});
}
private void MapHandleTest2(IApplicationBuilder applicationBuilder)
{
applicationBuilder.Run(async context =>
{
await context.Response.WriteAsync("this is middleware3HandleTest2 For Map start... ");
});
}

  Map还有个特殊的方法,MapWhen, 它接收一个Func<HttpContext, bool>的参数,可以根据Http请求上下文做一些逻辑判断。然后继续执行管道

             app.MapWhen(context => context.Request.Query.ContainsKey("branch"),
build =>
build.Run(async context =>
{
var branchVer = context.Request.Query["branch"];
await context.Response.WriteAsync($"Branch used = {branchVer}");
})
);

,这里再贴张.net core 自带的中间件

  

创建自定义中间件&&模拟Core的请求管道

  管道的实现机制由ApplicationBuilderRequestDelegate 组成。RequestDelegate是Middleware的核心,Use方法会将RequestDelegate加入到ApplicationBuilder 中去,最后执行Build方法,把所有RequestDelegate reverse之后挨个执行一遍。

  接下来编写一个自定义的Middleware。

    public class RequestTestMiddleware
{
private readonly RequestDelegate _next; //中间件核心RequestDelegate,_next 表示执行下一个中间件。
public RequestTestMiddleware(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext context)
{
context.Response.WriteAsync("hello this is my RequestTestMiddleware");
return _next(context); //覆盖delegate 的Inboke方法,将http上下文传入下一个中间件
}
} public static class RequestTestMiddlewareExtensions
{
public static IApplicationBuilder UseRequestTest(this IApplicationBuilder builder) //使用扩展方法使我们的中间件对外开放。
{
return builder.UseMiddleware<RequestTestMiddleware>(); //将我们中间件加入到IApplicationBuilder中去。
}
}
  //在StartUp 中使用我们的自定义中间件。
app.UseRequestTest();

Http请求管道的模拟构建

     /// <summary>
/// 拿到请求上下文,返回一个委托
/// </summary>
/// <param name="contex"></param>
/// <returns></returns>
public delegate Task RequestDelegate(Context contex);
/// <summary>
/// 模拟http请求上下文
/// </summary>
public class Context
{ }

RequestDelegate和Context

         public static IList<Func<RequestDelegate, RequestDelegate>> _list = new
List<Func<RequestDelegate, RequestDelegate>>();
static void Main(string[] args)
{
Use(next => //加入中间件1
{
return context =>
{
Console.WriteLine("this is use middleware1");
return next.Invoke(context);
};
});
Use(next => //加入中间件2
{
return context =>
{
Console.WriteLine("this is use middleware2");
return next.Invoke(context);
};
});
RequestDelegate end = context =>
{
Console.WriteLine("this is end..."); //管道
return Task.CompletedTask;
};
_list.Reverse();
foreach (var middleware in _list)
{
end = middleware.Invoke(end);
}
end.Invoke(new Context()); //实例化一个上下文实例
Console.ReadLine();
}
/// <summary>
/// 将middleware 加入到list(applicationbuilder)中
/// </summary>
public static void Use(Func<RequestDelegate, RequestDelegate> iMiddleware)
{
_list.Add(iMiddleware);
}

Use middleware和管道执行

Jesse博客学习笔记。传送门=》 http://video.jessetalk.cn/

Core篇——初探Core的Http请求管道&&Middleware的更多相关文章

  1. Core篇——初探Core的认证,授权机制

    目录 1.Cookie-based认证的实现 2.Jwt Token 的认证与授权 3.Identity Authentication + EF 的认证 Cookie-based认证的实现 cooki ...

  2. Core篇——初探Core配置管理

    文章目录 1.命令行配置 2.Json文件配置 3.配置文件文本至C#对象实例的映射 4.配置文件热更新 5.总结 命令行的配置 我们首先来创建一个.net core 的控制台项目,然后引入.net ...

  3. Core篇——初探IdentityServer4(OpenID Connect模式)

    Core篇——初探IdentityServer4(OpenID Connect客户端验证) 目录 1.Oauth2协议授权码模式介绍2.IdentityServer4的OpenID Connect客户 ...

  4. Core篇——初探IdentityServer4(客户端模式,密码模式)

    Core篇——初探IdentityServer4(客户端模式,密码模式) 目录 1.Oatuth2协议的客户端模式介绍2.IdentityServer4客户端模式实现3.Oatuth2协议的密码模式介 ...

  5. Core篇——初探依赖注入

    目录 1.DI&&IOC简单介绍 2.UML类图中六种关联关系 3..net core 中DI的使用 4..net core DI初始化源码初窥 DI&&IOC简单介绍 ...

  6. 比较ASP.NET和ASP.NET Core[经典 Asp.Net v和 Asp.Net Core (Asp.Net Core MVC)]

    ASP.NET Core是.与.Net Core FrameWork一起发布的ASP.NET 新版本,最初被称为ASP.NET vNext,有一系列的命名变化,ASP.NET 5.0,ASP.NET ...

  7. ASP.NET Core Blazor 初探之 Blazor Server

    上周初步对Blazor WebAssembly进行了初步的探索(ASP.NET Core Blazor 初探之 Blazor WebAssembly).这次来看看Blazor Server该怎么玩. ...

  8. ASP.NET Core 运行原理解剖[3]:Middleware-请求管道的构成

    在 ASP.NET 中,我们知道,它有一个面向切面的请求管道,有19个主要的事件构成,能够让我们进行灵活的扩展.通常是在 web.config 中通过注册 HttpModule 来实现对请求管道事件监 ...

  9. Net Core 的公共组件之 Http 请求客户端

    Net Core 的公共组件之 Http 请求客户端 想必大家在项目开发的时候应该都在程序中调用过自己内部的接口或者使用过第三方提供的接口,咱今天不讨论 REST ,最常用的请求应该就是 GET 和 ...

随机推荐

  1. 高德地图开发之获取SHA1码

    通过Android Studio获取SHA1 第一步.打开 Android Studio 的 Terminal 工具. 第二步.输入命令:keytool -v -list -keystore  key ...

  2. Websphere 手动模拟删除应用操作

    Websphere  手动模拟删除应用操作 切记:不要在程序还在运行的时候,直接的remove掉应用程序,不然,会发生意外的错误.       最近,在项目中,不小心手动移除了正在运行的应用,发现se ...

  3. SIFT算法总结:用于图像搜索

    原始文章链接:http://bubblexc.com/y2011/163/ 原文链接:http://blog.csdn.net/cserchen/article/details/5606859 关于三 ...

  4. 如何防范自己的IP泄漏

    在正式进行各种“黑客行为”之前,黑客会采取各种手段,探测(也可以说“侦察”)对方的主机信息,以便决定使用何种最有效的方法达到自己的目的.来看看黑客是如何获知最基本的网络信息——对方的IP地址:以及用户 ...

  5. 还是UVa340

    #include<stdio.h> #define maxn 1010 int main() { int num,a[maxn],i,j,b[maxn]; ; &&num) ...

  6. Swfit4.0中JSON与模型原生互转(JSONEncoder/JSONDecoder的使用)

    在Objective-C中,苹果并没有提供JSON转模型(模型转JSON)的接口,往往在开中需要添加第三库来处理JSON数据,比如:JsonModel.MJExtension.Mantle.JsonK ...

  7. 优动漫PAINT新建文件

    在优动漫PAINT软件中展开任何一项操作之前,都需要新建或打开图形文件.新建文件之后,用户可根据自己的需求进行相应的设置,这样将大大节省后期制作的时间! 在优动漫PAINT中新建图形文件的方法: 方法 ...

  8. 企业级任务调度框架Quartz(9) Quartz之作业触发器Trigger

    前序:      我们已经大概对Quartz的基本有了一个大概的认识:现在我们将要逐渐对Quartz的各个重要组件进行学习:前面已经对job进行了详细讲解,现在我们来认识下它的一个重要兄弟,没有它,作 ...

  9. IDEA使用GsonFormat完成JSON和JavaBean之间的转换

    原文地址:https://www.leshalv.net/posts/12625/ 前言: 之前处理接口传来的一堆数据,用jsonObject很难受,后面就用gosn来弄,配合这个工具体验很好. 转: ...

  10. SQL SEVER 递归查询

    with ts as ( --首先要查询出最原始父级的信息 union all --全连接 select a.fitemclassid,a.fitemid, a.fnumber,a.Fparentid ...