ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

<一>ASP.NET Core 管道

2022-04-26 00:31:36  阅读:171  来源: 互联网

标签:Core ASP app 中间件 IApplicationBuilder 管道 context NET public


ASP.NET Core应用程序提供了处理每个请求的完整控制。在这个请求管道中,我们可以动态配置各种业务逻辑对应的中间件(middleware),从而达到服务端可以针对不同用户做出不同的请求响应。

一、管道

ASP.NET Core应用程序在创建程序宿主之前需要构建一个管道。而IApplicationBuilder 是用来构建请求管道的.而请求管道,本质上就是对 HttpContext 的一系列操作,即通过对 Request 的处理,来生成 Reponse

namespace Microsoft.AspNetCore.Builder
{
    //
    // 摘要:
    //     Defines a class that provides the mechanisms to configure an application's request
    //     pipeline.
    public interface IApplicationBuilder
    {
        //
        // 摘要:
        //     Gets or sets the System.IServiceProvider that provides access to the application's
        //     service container.
        IServiceProvider ApplicationServices
        {
            get;
            set;
        }

        //
        // 摘要:
        //     Gets the set of HTTP features the application's server provides.
        IFeatureCollection ServerFeatures
        {
            get;
        }

        //
        // 摘要:
        //     Gets a key/value collection that can be used to share data between middleware.
        IDictionary<string, object?> Properties
        {
            get;
        }

        //
        // 摘要:
        //     Adds a middleware delegate to the application's request pipeline.
        //
        // 参数:
        //   middleware:
        //     The middleware delegate.
        //
        // 返回结果:
        //     The Microsoft.AspNetCore.Builder.IApplicationBuilder.
        IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware);

        //
        // 摘要:
        //     Creates a new Microsoft.AspNetCore.Builder.IApplicationBuilder that shares the
        //     Microsoft.AspNetCore.Builder.IApplicationBuilder.Properties of this Microsoft.AspNetCore.Builder.IApplicationBuilder.
        //
        // 返回结果:
        //     The new Microsoft.AspNetCore.Builder.IApplicationBuilder.
        IApplicationBuilder New();

        //
        // 摘要:
        //     Builds the delegate used by this application to process HTTP requests.
        //
        // 返回结果:
        //     The request handling delegate.
        RequestDelegate Build();
    }
}

从上面接口源代码中,IApplicationBuilder提供了几个管道构建的方法

1、Use  注册中间件

Use是我们非常熟悉的注册中间件的方法,就是将注册的中间件保存到其内部属性 _components 中。注册多个中间件的时候围绕着Next分别对RequestRespone做出相应的处理,B的执行会嵌套在A的里面,因此A是第一个处理Request,

并且最后一个收到Respone,这样就构成一个经典的的U型管道。

public IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)
{
    _components.Add(middleware);
    return this;
}
 app.Use(next =>
    {
        Console.WriteLine("A");
        return async (context) =>
        {
            // 1. 对Request做一些处理
            // TODO
 
            // 2. 调用下一个中间件
            Console.WriteLine("A-BeginNext");
            await next(context);
            Console.WriteLine("A-EndNext");
 
            // 3. 生成 Response
            //TODO
        };
    });
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

2、Build  创建一个请求管道

 Build 方法创建一个 RequestDelegate 类型的委托。可以看到首先定义了一个 404 的中间件,然后使用了Reverse函数将注册的中间件列表进行反转,因此首先执行我们所注册的最后一个中间件,输入参数便是一个 404 ,

依次执行到第一个中间件,按我们的注册顺序从里到外,一层套一层。那么根据多中间件注册的u型管道模型,最后response的信息是第一个注册的中间件,即返回404。

public RequestDelegate Build()
{
    RequestDelegate app = context =>
    {
        context.Response.StatusCode = 404;
        return Task.CompletedTask;
    }; 
    foreach (var component in _components.Reverse())
    {
        app = component(app);
    } 
    return app;
var builder = WebApplication.CreateBuilder(args);  //创建程序宿主

// Add services to the container.
builder.Services.AddRazorPages();

var app = builder.Build();    //创建管道

 3、Run 结束管道向下调用

在注册的中间件中,是通过 Next 委托串连起来的,如果在某一个中间件中没有调用 Next 委托,则该中间件将做为管道的终点。因此通过管道的串联调用,可以在管道中进行拦截,比如授权中间件,当授权成功后才进入Next,如果授权不成功则response。

如果流程正常走,那我们在最后一个中间件不应该再调用 Next 委托,而使用Run 扩展方法来注册最后一个中间件。

public static class RunExtensions
{
    public static void Run(this IApplicationBuilder app, RequestDelegate handler)
    {
        if (app == null)
        {
            throw new ArgumentNullException(nameof(app));
        }
 
        if (handler == null)
        {
            throw new ArgumentNullException(nameof(handler));
        }
        app.Use(_ => handler);
    }
}
app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

二、中间件

1、app.UseMiddleware()自定义中间件委托函数

从Use方法中可以看到所谓的中间件实际上就是个委托(Func<RequestDelegate, RequestDelegate>) 。 ASP.NET Core 提供了一个更加具体的中间件的概念,我们在大部分情况下都会将中间件定义成一个单独的类型,使代码更加清晰。

因此一般都使用自定义中间件委托函数注入中间件。自定义使用中间件有两种方式:

  • 通过继承IMiddleware实现(需要注入服务)
public class TestMiddleWare : IMiddleware
    {
        public Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            context.Response.WriteAsync("中间件类A");
            return next(context);
        }
    }
services.AddSingleton<TestMiddleWare>();  
app.UseMiddleware<TestMiddleWare>();
  • 通过约定实现
public class TestMiddleWare
    {
        public readonly RequestDelegate _next;
        public TestMiddleWare(RequestDelegate next)
        {
            _next = next;
        }
        public Task InvokeAsync(HttpContext context)
        {
            context.Response.WriteAsync("中间件类A");
            return _next(context);
        }
    }
app.UseMiddleware<TestMiddleWare>();

 

标签:Core,ASP,app,中间件,IApplicationBuilder,管道,context,NET,public
来源: https://www.cnblogs.com/choii/p/16180108.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有