<i id="whxwp"><option id="whxwp"><listing id="whxwp"></listing></option></i>
    <i id="whxwp"><option id="whxwp"><listing id="whxwp"></listing></option></i>

    <i id="whxwp"><option id="whxwp"></option></i>

    <delect id="whxwp"><rp id="whxwp"><big id="whxwp"></big></rp></delect>

      <i id="whxwp"><option id="whxwp"><listing id="whxwp"></listing></option></i>

      <i id="whxwp"><option id="whxwp"><listing id="whxwp"></listing></option></i>

        Asp.net core中间件实现原理及用法解说

        简述asp.net core中间件的实现思路

         原文地址:https://www.cnblogs.com/shengyu-kmust/p/11583974.html

        一次http请求的过程,就是对一个Request请求进行若干次逻辑处理,并最终设置Response的过程。从代码的实现维度看,由于Request和Response都在HttpContext里,可将此过程表示为“以一个httpContext为输入的委托函数”,即delegate Task RequestDelegate(HttpContext context),为方便此文的描述,我们将此委托函数暂时称为“请求处理逻辑”

         分享图片

         

        而中间件的作用,就是在请求的后面加入一个处理逻辑,这个处理逻辑是以“前一个请求处理逻辑”为输入,并经过中间件自己的处理后,返回一个“新的请求处理逻辑”。所以从代码上可将“中间件”表式为以一个“请求处理逻辑”为输入并返回另一个“请求处理逻辑”的委托,即Func<RequestDelegate,RequestDelegate>。而多个中间件即表示为List<Func<RequestDelegate,RequestDelegate>>。

         分享图片

         

        Asp.net core中间件的核心功能就是如何将一系列的中间件,合并成一个“请求处理逻辑”的过程,即如何将List<Func<RequestDelegate,RequestDelegate>>合并生成一个RequestDelegate。合并逻辑如下

         分享图片

         分享图片

        上面的代码有两个地方要注意

        1、asp.net core会默认在请求的最后加入一个“404”处理的中间件。   

        2、合并时,组件是先反序后再循环的

           因先加入的中间件要先执行,所以在合并时,第一个中间件要最后合并,即要倒序后再循环合并中间件

         

        如何使用中间件

        使用中间件有四种方法:Use、Run、Map和使用Middleware class,但前三种方法最终调用的都是Use方法,我们来看看Use方法的实现逻辑,如下

         分享图片

         

        即use方法只是在中间件列表(_components)的最后再加入一个中间件

         

        下面详细描述四种方法的用法

         

        Use的用法

        Ues的用法有两种

        用法一

        调用IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware),此用法需在middleware委托里自己控制是否要进入下一个中间件,并且要自己创建一个RequestDelegate并返回,写法会比较复杂。

        示例如下

         分享图片

        用法二

        调用IApplicationBuilder Use(this IApplicationBuilder app, Func<HttpContext, Func<Task>, Task> middleware),这是一个扩展方法,此方法不用自己创建RequestDelegate并返回,写法比较简洁。它最终调用的方法还是用法一中的实现,此方法的实现代码如下。

         分享图片

        示例如下

         分享图片

         

        需注意:上面的两种Use用法,在第二个中间件时,并没有再调用下一个中间件,这是为了确保http请求不会进入到asp.net core默认的最后一个404中间件,因为最后一个404中间件设置了status code,而一但response body之前已经开始写入时,是不能再改变status code或是request header的,否则会报错。微软的官方文档里要求中间件的使用要遵循如下规则:如response body改变后就不要再调用下一个中间件,避免下一个中间件对上一个中间件的httpcontext内容的污染。(本文示例为演示目的,未遵循此约定)

         分享图片

         

         

        run的用法

        run方法的实现代码如下

         分享图片

        分享图片

        注意:从run方法的实现的代码可以看出,run是不会再执行下一个中间件的,所以第一个中间run方法后面的中间件都不会起作用。所以一般用run时都是放在中间件的最后

         

         

        map的用法

        map其实准确来说不是中间件的用法,而是新开一个“中间件请求路线分支”,在这个“分支”里,可以再用use和run方法来组件一个新的中间件逻辑。

        示例如下

         分享图片

        如上示例,请求地址当能匹配上/test里,才会启用map里的中间件

         

        Middleware class的用法

        Middleware class不需要继承任何类或是接口,但必须有名为Invoke,返回类型为Task,且第一个参数为HttpContext类型的方法。

        示例如下

         分享图片

        分享图片

         

         

         

        Asp.net core内置中间件的介绍

         

        中间件名称

        如何使用及说明

        Authentication

        App.UseAuthentication,验证当前请求的用户,并设置HttpContext.User,当OAuth callbacks时,会中止执行下一个中间件。放到要用到用户验证的中间件前面

        Static File

        app.UseStaticFiles(),判断当前请求是否为静态文件,如果是则中止执行下一个中间件,否则继续下一个中间件。放到管道的最前

        Response Caching

        app.UseResponseCaching(),缓存中间件

        MVC

        app.UseMvc(),将MVC引入到中间件管道,如果请求的地址能找到对应的MVC路由,则中止执行下一个中间件。放到管道的最后。

        Exception

        app.UseDeveloperExceptionPage();或app.UseExceptionHandler();用于处理程序的异常信息。放到管道的最前

        Authorization 

        授权中间件。不需直接引用,App.UseMvc()会在内部调用,并配合app.UseAuthentication()一起使用。

         

         

        中间件的总结

        1、通过use,run,map,middleware class四种方法使用

        2、使用多个中间件时,需注意中间件的顺序

        3、在设计中间件时,请遵循“责任分离”原则,即一个中间件只对“单一责任”进行处理,如验证用户、授权等。

        4、如果对response body做了修改后,请不要再执行下一个中间件

        相关文章
        相关标签/搜索
        三期內必开一肖 迁安市| 湛江市| 宝山区| 南汇区| 涞水县| 山西省| 正宁县| 同德县| 呈贡县| 凌海市| 湘阴县| 保定市| 米易县| 阿城市| 休宁县| 临洮县| 涞水县| 康马县| 班戈县| 隆昌县| 封开县| 奉化市| 汾西县| 嘉黎县| 长治市| 衡东县| 阳江市| 惠水县| 靖州| 册亨县| 湘潭县| 衡山县| 苏尼特左旗| 汝城县| 佛山市| 临沭县| 岱山县| 阿拉善左旗| 五家渠市| 兴海县| 灯塔市| 江永县| 永川市| 开阳县| 蒙自县| 治县。| 会东县| 始兴县| 漯河市| 芦山县| 柏乡县| 班玛县| 全椒县| 赫章县| 山西省| 商丘市| 廊坊市| 彭州市| 万州区| 兴义市| 眉山市| 阆中市| 招远市| 石首市| 连平县| 鄂尔多斯市| 中牟县| 武汉市| 通化县| 湟源县| 姚安县| 枣强县| 凌源市| 汶上县| 塔城市| 台中市| 河西区| 瓦房店市| 金乡县| 遂溪县| 监利县| 逊克县| 山西省| 沙雅县| 淄博市| 东乡| 雅安市| 加查县| 固安县| 金门县| 浦城县| 弥勒县| 乃东县| 巴马| 湾仔区| 云浮市| 攀枝花市| 德保县| 渝北区| 安图县| 钦州市| 遂川县| 贺兰县| 达拉特旗| 藁城市| 郴州市| 莱芜市| 响水县| 长顺县| 威远县| 桐柏县| 涪陵区| 太谷县| 泰来县| 普洱| 石河子市| 贵德县| 磴口县| 宜昌市| 会东县| 民和| 富裕县| 宁津县| 潜江市| 阆中市| 平罗县| 营山县| 黄山市| 上杭县| 晋宁县| 乌兰察布市| 神木县| 黔江区| 和田县| 缙云县| 天门市| 凤山市| 秀山| 文成县| 晋江市| 钟山县| 岑巩县| 青川县| 广饶县| 昌图县| 陆良县| 湖州市| 呼图壁县| 延安市| 高唐县| 隆安县| 湄潭县| 忻州市| 木兰县| 正安县| 长春市| 兰溪市| 沿河| 中超| 瑞安市| 宝坻区| 九寨沟县| 礼泉县| 宁陵县| 河津市| 临澧县| 竹溪县| 时尚| 滁州市| 清新县| 类乌齐县| 洪江市| 庆城县| 邯郸县| 广平县| 怀柔区| 沐川县| 汤原县| 新河县| 丽江市| 即墨市| 垣曲县| 登封市| 个旧市| 临西县| 海伦市| 阆中市| 壤塘县| 黄石市| 永善县| 菏泽市| 青州市| 苗栗市| 昭平县| 徐水县| 邵阳市| 黑龙江省| 东阿县| 什邡市| 景东| 商城县| 汉寿县| 彰化县| 武威市| 福贡县| 仁布县| 西林县| 安达市| 石屏县| 綦江县| 庆云县| 凯里市| 竹北市| 黎川县| 壤塘县| 福贡县| 达孜县| 砚山县| 兴安县| 华蓥市| 汶上县| 利津县| 阿鲁科尔沁旗| 昭觉县| 盐山县| 富顺县| 大洼县| 陆川县| 伊宁县| 绩溪县| 武功县| 海原县| 八宿县| 大同市| 乐亭县| 镇康县| 绵阳市| 河池市| 应城市| 兰溪市| 祥云县| 肇州县| 博野县| 肇庆市| 曲靖市| 兰坪| 和平县| 三台县| 石棉县| 开江县| 青海省| 天峻县| 黄平县| 迁安市| 阜新| 绥中县| 山丹县| 怀化市| 乐昌市| 安溪县| 嵩明县| 上林县| 遵化市| 仲巴县| 双流县| 伊通| 广安市| 左云县| 张家口市| 元朗区| 平谷区| 沙河市| 沾益县| 奉节县| 陇川县| 涿鹿县| 阿拉善左旗| 陇西县| 齐齐哈尔市| 九江市| 扎赉特旗| 通道| 海城市| 太谷县| 玉溪市| 新密市| 溆浦县| 香河县| 曲沃县| 绥阳县| 长兴县| 任丘市| 青浦区| 深圳市| 五寨县| 阜宁县| 延安市| 高邮市| 长宁区| 兴隆县| 英吉沙县| 竹北市| 隆德县| 通山县| 分宜县| 张家川| 龙山县| 南昌市| 万源市| 瑞金市| 瓦房店市| 怀柔区| 江门市| 郓城县| 南汇区| 虞城县| 阳朔县| 分宜县| 敖汉旗| 蒙山县| 迭部县| 电白县| 勐海县| 高邮市| 南乐县| 苏州市| 石河子市| 湖南省| 正定县| 北辰区| 富民县| 临潭县| 望城县| 莱芜市| 铁岭市| 建宁县| 彰武县| 三门县| 宜兰市| 瑞金市| 顺昌县| 蓝田县| 镇坪县| 浦城县| 特克斯县| 杂多县| 盈江县| 哈尔滨市| 友谊县| 崇州市| 黎平县| 特克斯县| 额敏县| 金坛市| 黄冈市| 南江县| 白沙| 都安| 静宁县| 鹤山市| 巴彦淖尔市| 抚顺县| 伊宁市| 慈溪市| 将乐县| 双柏县| 芦溪县| 泸定县| 灵石县| 松原市| 万源市| 洪湖市| 永平县| 枣强县| 满洲里市| 航空| 哈尔滨市| 永登县| 孝感市| 巴东县| 贵南县| 梓潼县| 驻马店市| 武邑县| 贵南县| 喀喇沁旗| 新蔡县| 澄迈县| 云林县| 邢台县| 京山县| 简阳市| 杭锦后旗| 连南| 崇义县| 梁山县| 民丰县| 怀远县| 屯昌县| 上犹县| 德钦县| 舞钢市| 阿荣旗| 孝昌县| 花莲县| 离岛区| 岱山县| 大港区| 荣成市| 虞城县| 庄浪县| 自贡市| 商都县| 乌恰县| 永兴县| 宜君县| 榆社县| 化州市| 历史| 卢氏县| 盐源县| 金山区| 嫩江县| 扶绥县| 宁强县| 庄河市| 长治县| 齐齐哈尔市| 安仁县| 唐河县| 寿阳县| 彰武县| 大埔区| 黄梅县| 乌苏市| 郁南县| 阿巴嘎旗| 偃师市| 宣威市| 磐石市| 龙泉市| 神农架林区| 柏乡县| 屯昌县| 六安市| 德格县| 洛扎县| 广德县| 呈贡县| 勃利县| 微山县| 和田市| 同仁县| 彭水| 谢通门县| 子洲县| 桐城市| 进贤县| 冕宁县| 阿城市| 镇康县| 闽清县| 拉萨市| 太原市| 东城区| 日喀则市| 田林县| 新建县| 新田县| 乌鲁木齐市| 绥德县| 广安市| 崇明县| 庆阳市| 建宁县| 家居| 晋州市| 江安县| 陇南市| 石城县| 望奎县| 新干县| 池州市| 宜城市| 拉孜县| 霍城县| 鲁甸县| 潜江市| 寿光市| 康平县| 都安| 呼伦贝尔市| 莱州市| 共和县| 甘孜县| 赫章县| 福清市| 惠来县| 陆良县| 汝州市| 新丰县| 台南县| 曲沃县| 灵璧县| 延寿县| 望奎县| 竹山县| 皮山县| 漾濞| 永川市| http://bbs.jp1860attezpto.fun http://bbs.jp1860deposito.fun http://bbs.jp1860zarketo.fun http://bbs.jp1860delivero.fun http://bbs.jp1860fito.fun http://3g.jp1860fullo.fun http://3g.jp1860chooseo.fun http://wap.jp1860apparelo.fun http://m.jp1860studyo.fun http://www.jp1860districto.fun http://www.jp1860claizo.fun http://bbs.jp1860featureo.fun http://3g.jp1860fasto.fun http://wap.jp1860leaveo.fun http://m.jp1860blocko.fun