ASP.NET Core中Middleware的使用
https://www.cnblogs.com/shenba/p/6361311.html
ASP.NET 5中Middleware的基本用法
在ASP.NET 5里面引入了OWIN的概念,大致意思是将网站部署、服务器、中间组件以及应用分离开,这里提到的Middleware就是中间组件。
这里引用asp.net网站的介绍图

Middleware的作用有点类似于httpmodule,服务器接收到的请求都会传递到各个Middleware,多个Middleware形成一个处理管道。
由于不针对于特定的请求,所以Middleware的执行范围是在Application之外,这种模式很适合处理日志记录,权限验证和事务处理,也可以理解为AOP的一种实现方式。
在ASP.NET 5里面,ASP.NET Identity就提供了用于权限认证的Middleware,在Startup类里面调用UseXXX的方法就可以加入支持不同权限验证的Middleware,具体可以参考ASP.NET Identity的介绍。
除了Middleware除了第三方组件提供的之外,我们还可以实现自定义的Middleware。
在ASP.NET 5里面,我们自定义一个Middleware需要继承类OwinMiddleware,如下形式
Middleware In ASP.NET 5
构造方法传入了下一个Middleware的实例,用于在执行完当前Middleware之后,执行下一个Middleware。
然后在Startup的Configuration方法里调用

public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Use<LoggerMiddleware>(new TraceLogger());
}
}

以上是ASP.NET 5中Middleware的使用简述。
———————————————————————————————————————————————————————————————————— ASP.NET Core的Middleware的用法
而在最新版的ASP.NET Core中Middleware的使用方式有了变化,下面通过一步步来看如何在ASP.NET Core中创建自定义的Middleware,描述一下新版中如何是定义Middleware以及多个Middleware的调用
1.创建一个空白的ASP.NET Core Web项目


2.然后在项目的根目录创建一个Middlewares文件夹

3. 接下来将创建多个不同功能的Middleware
a.创建输出内容的Middleware
在没有使用任何Middleware时,这时候的项目能运行,运行之后只会输出Hello World。那是因为在Startup的Configure方法里,有一个默认的Run
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
不管输入什么url路径,都只会返回Hello World,这也可以理解为一个Middleware,是一个兜底的处理。
其实在ASP.NET Core里面,MVC的引入也是通过Middleware的形式实现的,在引入MVC的组件后,可以通过app.UseMvc()方法引入组件,这里不详述。
回到即将创建的自定义的Middleware,在新版中创建自定义的Middleware,不需要继承OwinMiddleware类,也没有提供这类的定义。
自定义的Middleware看起来跟普通的class没什么区别,下面在Middlewares文件夹新建一个ContentMiddleware类,然后编写代码如下
从这个类我们看到,没有继承任何类或者实现任何接口,但是方法的签名类似于之前版本的实现。
在.NET Core版本中,自定义Middleware提供一个包含RequestDelegate 类型参数的构造方法,另外提供如下格式的Invoke方法签名即可
public async Task Invoke(HttpContext httpContext)。
其中RequestDelegate实例表示的是下一个执行的Middleware,这点跟OwinMiddleware类似。
Invoke方法接收的是HttpContext类似的参数,相比之前OwinConext,感觉这样更加直接。
这个ContentMiddleware的实现是,判断请求的路径如果是/middleware,就返回内容,否则交给下一个组件处理。
定义完成之后,在Startup的Configure方法中,在app.Run()代码之前加入下面的代码
app.UseMiddleware<ContentMiddleware>();
运行之后输入http://localhost:53814/middleware就会看到浏览器输出了以下内容
”Handled by content middleware“
如果输入其他url还是会显示”Hello world”。
b.创建可终止后续请求的Middleware
刚才提供Middleware的作用可用于校验请求内容,然后根据请求信息作出是否继续处理请求的操作。下面我们创建一个Middleware,判断如果是IE浏览器就返回403状态码,那么后续的请求将不被执行。
在Middlewares文件夹创建ValidateBrowserMiddleware类,填入代码如下
同样在Startup的Configure方法加入引用,把这个组件放入到其他Middleware引用之前。
Middleware的引用顺序很关键,最先引用的最先处理Request,并且是最后处理Response,是一种后进先出的处理顺序。
这时候运行网站,如果是在IE浏览器下访问,那么会返回403的错误信息(禁止访问),后续的请求都不会执行,提早中断了请求。
c.修改请求上下文的Middleware
这里说的上下文是Httpcontext,这里有一个Items属性,可以存放一些数据用于当前的请求。
在Middlewares文件夹创建EditContextMiddleware,修改代码如下
这个Middleware在httpContext中加入了一个是否IEBrowser的数据项,然后接着执行后续的组件,也就是说后续的组件可以在httpContext中获取这个值。
基于这个改动我们可以修改ValidateBrowserMiddleware的Invoke方法的实现

public async Task Invoke(HttpContext httpContext)
{
var isIEBrowser = httpContext.Items["IEBrowser"] as bool?;
if (isIEBrowser.GetValueOrDefault())
{
httpContext.Response.StatusCode = 403;
}
else
{
await _nextDelegate.Invoke(httpContext);
}
}

这个改动的一个前提是EditContextMiddleware的引入必须在ValidateBrowserMiddleware之前,如下
d.最后一个是修改Repsonse的Middleware
之前的都是处理Request或者修改HttpContext内容,根据上一个Middleware的处理结果来修改Response也是常见的做法。
在Middlewares文件夹创建类StatusCodeMiddleware,代码内容如下
上述代码的根据不同的Http状态码返回Response输出,如果是IE访问那么会显示一段文字,而不是一个403错误页。
由于处理的是Repsonse的内容,因此是在Invoke方法之后执行,并且这个Middleware必须放在第一位,这样才能确保这Middleware处理的是最后一个Repsonse,因为Repsonse的处理顺序跟Request的处理顺序是相反的。
StatusCodeMiddleware的引用代码:
至此,已经使用了4个自定义的Middleware,对于一个请求每个middleware的处理顺序如下

以上是ASP.NET Core中使用自定义Middleware的基本用法,基于这个实现我们做更多有意义的事情,比如日志记录、事务处理等。
上述例子的代码在如下路径
https://github.com/shenba2014/AspDotNetCoreMvcExamples/tree/master/CustomMiddleware
ASP.NET Core中Middleware的使用的更多相关文章
- 如何设计出和 ASP.NET Core 中 Middleware 一样的 API 方法?
由于笔者时间有限,无法写更多的说明文本,且主要是自己用来记录学习点滴,请谅解,下面直接贴代码了(代码中有一些说明): 01-不好的设计 代码: using System; namespace Desi ...
- ASP.NET Core中,UseDeveloperExceptionPage扩展方法会吃掉异常
在ASP.NET Core中Startup类的Configure方法中,有一个扩展方法叫UseDeveloperExceptionPage,如下所示: // This method gets call ...
- ASP.NET Core中使用自定义路由
上一篇文章<ASP.NET Core中使用默认MVC路由>提到了如何使用默认的MVC路由配置,通过这个配置,我们就可以把请求路由到Controller和Action,通常情况下我们使用默认 ...
- ASP.NET Core 中文文档 第三章 原理(1)应用程序启动
原文:Application Startup 作者:Steve Smith 翻译:刘怡(AlexLEWIS) 校对:谢炀(kiler398).许登洋(Seay) ASP.NET Core 为你的应用程 ...
- ASP.NET Core 中文文档 第三章 原理(6)全球化与本地化
原文:Globalization and localization 作者:Rick Anderson.Damien Bowden.Bart Calixto.Nadeem Afana 翻译:谢炀(Kil ...
- ASP.NET Core 中文文档 第三章 原理(13)管理应用程序状态
原文:Managing Application State 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:高嵩 在 ASP.NET Core 中,有多种途径可以对应用程序的状态进行 ...
- ASP.NET Core中显示自定义错误页面-增强版
之前的博文 ASP.NET Core中显示自定义错误页面 中的方法是在项目中硬编码实现的,当有多个项目时,就会造成不同项目之间的重复代码,不可取. 在这篇博文中改用middleware实现,并且放在独 ...
- 在ASP.NET Core使用Middleware模拟Custom Error Page功能
一.使用场景 在传统的ASP.NET MVC中,我们可以使用HandleErrorAttribute特性来具体指定如何处理Action抛出的异常.只要某个Action设置了HandleErrorAtt ...
- ASP.NET Core中间件(Middleware)实现WCF SOAP服务端解析
ASP.NET Core中间件(Middleware)进阶学习实现SOAP 解析. 本篇将介绍实现ASP.NET Core SOAP服务端解析,而不是ASP.NET Core整个WCF host. 因 ...
随机推荐
- Perl 学习笔记-正则表达式基础篇
1.Perl中的正则表达式 在Perl中叫做模式, 是一个匹配(或不匹配)某字符串的模板, 是一种小程序, 对于一个字符串, 要么匹配, 要么不匹配. 使用简易模式: 将模式写在一对正斜线(/)中即可 ...
- list 返回列表null替换
function formatt(rec, val, index) { if (rec === null || rec == "null") { return "0&qu ...
- 利用APT实现Android编译时注解
摘要: 一.APT概述 我们在前面的java注解详解一文中已经讲过,可以在运行时利用反射机制运行处理注解.其实,我们还可以在编译时处理注解,这就是不得不说官方为我们提供的注解处理工具APT (Anno ...
- 【小梅哥SOPC学习笔记】设置Eclipse在编译(build)前自动保存源代码文件
设置Eclipse在编译(build)前自动保存源代码文件 Eclipse 常用设置之让Eclipse在编译(build)前自动保存源代码文件 一.让Eclipse在编译(build)前自动保存源代码 ...
- 2.5 《硬啃设计模式》第7章 车手选车 - 生成器(Builder Pattern)
某赛车游戏,玩家可以选择不同的车,这些车其实是采用不同性能的配件组成的,如:车胎.发动机等. 玩家选择一部车,其实就是new了一部车. 你如何考虑“new car”的代码? 要new这个车,可能需要先 ...
- mysql数据库使用sql查询数据库大小及表大小
网上查了很多资料,最后发现一个可行的,分享如下: 数据库大小查询: select concat(round(sum(DATA_LENGTH/1024/1024),2),'M') from inform ...
- 在JS中,将text框中数据格式化,根据不同的小数位数,格式化成对应的XXX,XXX,XXX.XX(2位小数) 或者XXX,XXX,XXX(0位小数)
//在JS中,将text框中数据格式化,根据不同的小数位数,格式化成对应的XXX,XXX,XXX.XX(2位小数) 或者XXX,XXX,XXX(0位小数) function formatNum(num ...
- Starling开源手势库AcheGesture
http://news.9ria.com/2012/1220/25686.html AcheGesture -一个Flash的开源框架 特点: 提供7个基本的手势,包括:单击.双击.捏.来回滑动.猛击 ...
- MongoDB基础知识记录
MongoDB基础知识记录 一.概念: 讲mongdb就必须提一下nosql,因为mongdb是nosql的代表作: NoSQL(Not Only SQL ),意即“不仅仅是SQL” ,指的是非关系型 ...
- 判断AVL树是否平衡
AVL树是高度的平衡二插搜索树,其左子树和右子树的高度之差不超过1(树中的左子树和右子树都是AVL树),维持这个高度之差就要控制它的平衡因子.那么判断一颗AVL树是否平衡就需要判断它的左子树和右子树高 ...