打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
ASP.NET Core WebAPI 学习笔记(4):Middleware(上)


来源:星辰.Lee

链接:cnblogs.com/niklai/p/5665272.html


第一部分:管道模型


1. Asp.Net管道


在之前的Asp.Net里,主要的管道模型流程如下图所示:



请求进入Asp.Net工作进程后,由进程创建HttpWorkRequest对象,封装此次请求有关的所有信息,然后进入HttpRuntime类进行进一步处理。HttpRuntime通过请求信息创建HttpContext上下文对象,此对象将贯穿整个管道,直到响应结束。同时创建或从应用程序池里初始化一个HttpApplication对象,由此对象开始处理之前注册的多个HttpModule。之后调用HandlerFactory创建Handler处理程序,最终处理此次请求内容,生成响应返回。


下面用一个简单的Asp.Net程序来验证这个流程。


使用VS2015创建一个空的Asp.Net项目,根据向导添加HttpModule.cs、HttpHandler.cs、Global.asax文件


using System.Web;

namespace WebApplicationTest

{

    public class HttpModule1 : IHttpModule

    {

        public void Dispose()

        {

        }

        public void Init(HttpApplication context)

        {

            context.BeginRequest += (sender, e) =>

            {

                context.Response.Write('HttpModule1 request begin....
');

            };


            context.EndRequest += (sender, e) =>

            {

                context.Response.Write('HttpModule1 request end!
');

            };

        }

    }

    public class HttpModule2 : IHttpModule

    {

        public void Dispose()

        {

        }

        public void Init(HttpApplication context)

        {

            context.BeginRequest += (sender, e) =>

            {

                context.Response.Write('HttpModule2 request begin....
');

            };


            context.EndRequest += (sender, e) =>

            {

                context.Response.Write('HttpModule2 request end!
');

            };

        }

    }


    public class HttpModule3 : IHttpModule

    {

        public void Dispose()

        {

        }


        public void Init(HttpApplication context)

        {

            context.BeginRequest += (sender, e) =>

            {

                context.Response.Write('HttpModule3 request begin....
');

            };

            context.EndRequest += (sender, e) =>

            {

                context.Response.Write('HttpModule3 request end!
');

            };

        }

    }

}


using System.Web;

namespace WebApplicationTest

{

    public class HttpHandler : IHttpHandler

    {

        public bool IsReusable

        {

            get

            {

                return true;

            }

        }

        public void ProcessRequest(HttpContext context)

        {

            context.Response.ContentType = 'text/html';

            context.Response.Write('Hello world!
');

            context.Response.End();

        }

    }

}


配置Web.Config。以下是在IIS7环境下的配置内容。


 

   

   

 

 

   

   

     

   

   

     

     

     

   

 


启动调试,访问地址 http://localhost:5383/index.handler ,可以看到页面内容。



之前版本的Asp.Net MVC正是通过 UrlRoutingModule.cs 类和 MvcHandler.cs 类进行扩展从而实现了MVC框架。


2、Asp.Net Core管道


而在Asp.Net Core里面,管道模型流程发生了很大的变化:



IHttpModule和IHttpHandler不复存在,取而代之的是一个个中间件(Middleware)。


Server将接收到的请求直接向后传递,依次经过每一个中间件进行处理,然后由最后一个中间件处理并生成响应内容后回传,再反向依次经过每个中间件,直到由Server发送出去。


中间件就像一层一层的“滤网”,过滤所有的请求和相应。这一设计非常适用于“请求-响应”这样的场景——消息从管道头流入最后反向流出。


接下来将演示在Asp.Net Core里如何实现中间件功能。

 

第二部分、Middleware


其实,在这个系列的第一篇里面,已经展示了管道的一个简单用法。这里再详细讲解一下如何实现自定义管道。


Middleware支持Run、Use和Map三种方法进行注册,下面将展示每一种方法的使用方式。


一、Run方法


所有需要实现的自定义管道都要在 Startup.cs 的 Configure 方法里添加注册。


public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)

        {

            // 添加日志支持

            loggerFactory.AddConsole();

            loggerFactory.AddDebug();

            

            // 添加NLog日志支持

            loggerFactory.AddNLog();


            // 添加自定义中间件

            app.Run(async context =>

            {

                await context.Response.WriteAsync('Hello World!');

            });


            // 添加MVC中间件

            //app.UseMvc();

        }


启动调试,访问地址 http://localhost:5000/ ,页面显示Hello World!字样。



再次添加一个Run方法


public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)

        {

            // 添加日志支持

            loggerFactory.AddConsole();

            loggerFactory.AddDebug();

            // 添加NLog日志支持

            loggerFactory.AddNLog();


            // 添加自定义中间件

            app.Run(async context =>

            {

                await context.Response.WriteAsync('Hello World!');

            });

            app.Run(async context =>{

                await context.Response.WriteAsync('Hello World too!');

            });

            // 添加MVC中间件

            //app.UseMvc();

        }


启动调试,再次访问发现页面上只有Hello World!字样。


原因是:Run的这种用法表示注册的此中间件为管道内的最后一个中间件,由它处理完请求后直接返回。


二、Use方法 


public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)

        {

            // 添加日志支持

            loggerFactory.AddConsole();

            loggerFactory.AddDebug();

            

            // 添加NLog日志支持

            loggerFactory.AddNLog();


            // 添加自定义中间件

            app.Use(async (context, next) =>

            {

                await context.Response.WriteAsync('Hello World!');

            });


            // 添加MVC中间件

            //app.UseMvc();

        }


启动调试,访问页面同样显示Hello World!字样。我们发现使用Use方法替代Run方法,一样可以实现同样的功能。


再次添加一个Use方法,将原来的Use方法内容稍作调整,尝试实现页面显示两个Hello World!字样。



public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)

        {

            // 添加日志支持

            loggerFactory.AddConsole();

            loggerFactory.AddDebug();

            

            // 添加NLog日志支持

            loggerFactory.AddNLog();


            // 添加自定义中间件

            app.Use(async (context, next) =>

            {

                await context.Response.WriteAsync('Hello World!');

                await next();

            });


            app.Use(async (context, next) =>

            {

                await context.Response.WriteAsync('Hello World too!');

            });


            // 添加MVC中间件

            //app.UseMvc();

        }


启动调试,访问页面



将两个Use方法换个顺序,稍微调整一下内容,再次启动调试,访问页面,发现字样输出顺序也发生了变化。


public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)

        {

            // 添加日志支持

            loggerFactory.AddConsole();

            loggerFactory.AddDebug();

            

            // 添加NLog日志支持

            loggerFactory.AddNLog(); HelloworldMiddleware.cs 


            // 添加自定义中间件

            app.Use(async (context, next) =>

            {

                await context.Response.WriteAsync('Hello World too!');

                await next();

            });

            app.Use(async (context, next) =>

            {

                await context.Response.WriteAsync('Hello World!');

            });

            // 添加MVC中间件

            //app.UseMvc();

        }


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
ASP.NET Core笔记(5) - 中间件
ASP.NET CORE 管道模型及中间件使用解读
一不小心写了个WEB服务器
ASP.NET Core 中间件详解及项目实战
dotNET Core 3.X 请求处理管道和中间件的理解
ASP.NET应用程序生命周期趣谈(一)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服