OWIN系列之自己动手编写中间件
一、前言
1.基于OWIN的项目摆脱System.Web束缚脱颖而出,轻量级+跨平台,使得ASP.NET应用程序只需依赖这个抽象接口,不用关心所运行的Web服务器。
2.OWIN.dll介绍
使用反编译工具打开Owin.dll,你会发现类库中就只有一个IAppBuilder接口,所以说OWIN是针对.NET平台的开放Web接口。
3.Microsoft.Owin.dll
Microsoft.Owin.dll是微软对Owin的具体实现,其中就包括我们今天的主题"中间件"。下文将使用代码描述自定义基于Owin的"中间件"。
二、环境准备
1.Visual Studio 2015 Update1
2.tinyfox-2.3.2-common --用作Owin Host
三、项目基架搭建和介绍
1.创建一个空的Web站点,移除除了System的所有引用
2. 使用NuGet命令安装安装Microsoft.Owin
PM> Install-Package Microsoft.Owin
3.安装成功后的引用,可以看到,Owin.dll是依赖项,所以自动下载
图1 所有引用
4.查看Owin.dll结构和IAppBuilder接口代码
图2 Owin.dll结构
图3 IAppBuilder接口代码
5.OwinMiddleware介绍
OwinMiddleware 是位于Microsoft.Owin.dll中的一个抽象类,我们会用到OwinMiddleware中的Next,简单的说就是当前中间件无法匹配请求则会将请求转向下一个中间件处理,直至成功处理,当然这个取决你的程序中是否有转向代码,下文中将详细介绍。
四、自己动手编写中间件
1.新建类MyMiddleware继承OwinMiddleware并且实现Invoke函数,附代码;在Invoke中根据不同的URL PATH调用不同的处理方法
/// <summary>
/// OWIN "中间件" - MyMiddleware
/// </summary>
public class MyMiddleware : OwinMiddleware
{ /// <summary>
/// 构造函数,第一个参数必须为 OwinMiddleware对象 ;第一个参数是固定的,后边还可以添加自定义的其它参数
/// </summary>
/// <param name="next">下一个中间件</param>
public MyMiddleware(OwinMiddleware next)
: base(next)
{ } /// <summary>
/// 处理用户请求的具体方法,该方法是必须的
/// </summary>
/// <param name="c">OwinContext对象</param>
/// <returns></returns>
public override Task Invoke(IOwinContext c)
{
if (Next != null && c.Request.Path.Value != "/home/index")
{ var message1 = "NotFound\r\n";
var outbytes1 = Encoding.UTF8.GetBytes(message1);
c.Response.ContentType = "text/html; charset=utf-8";
c.Response.Write(outbytes1, , outbytes1.Length);
return Next.Invoke(c);
} // var urlPath = c.Request.Path;
// switch (urlPath) {
// ..........
// ..........
// 可以根据不同的URL PATH调用不同的处理方法
// 从而构成一个完整的应用。
// } var message = "Welcome to My Home!";
var outbytes = Encoding.UTF8.GetBytes(message);
c.Response.ContentType = "text/html; charset=utf-8";
c.Response.Write(outbytes, , outbytes.Length); return Task.FromResult<int>();
} }
介绍:
1.构造函数第一个参数必须为 OwinMiddleware对象,可从Microsoft.Owin.dll源码得知,这里不作话题。
2.我们在上面提到了“如果当前中间件无法匹配请求则会将请求转向下一个中间件处理”,上面的代码中的if如果成立,执行return Next.Invoke(c);后会找注册的下一个中间件,如果url匹配,会正确执行,并且执行return Task.FromResult<int>(0);结束当前请求。
2.新建类MyMiddleware2继承OwinMiddleware并且实现Invoke函数,之所以建立两个中间件,是为了演示”如果当前中间件无法匹配请求则会将请求转向下一个中间件处理",同样附上代码
/// <summary>
/// OWIN "中间件" - MyMiddleware2
/// </summary>
public class MyMiddleware2 : OwinMiddleware
{ /// <summary>
/// 构造函数,第一个参数必须为 OwinMiddleware对象 ;第一个参数是固定的,后边还可以添加自定义的其它参数
/// </summary>
/// <param name="next">下一个中间件</param>
public MyMiddleware2(OwinMiddleware next)
: base(next)
{
} /// <summary>
/// 处理用户请求的具体方法,该方法是必须的
/// </summary>
/// <param name="c">OwinContext对象</param>
/// <returns></returns>
public override Task Invoke(IOwinContext c)
{ if (Next != null && c.Request.Path.Value != "/user")
{ var message1 = "NotFound2!\r\n";
var outbytes1 = Encoding.UTF8.GetBytes(message1);
c.Response.ContentType = "text/html; charset=utf-8";
c.Response.Write(outbytes1, , outbytes1.Length);
return Task.FromResult();
} // var urlPath = c.Request.Path;
// switch (urlPath) {
// ..........
// ..........
// 可以根据不同的URL PATH调用不同的处理方法
// 从而构成一个完整的应用。
// } var message = "I'm MyMiddleware2";
var outbytes = Encoding.UTF8.GetBytes(message);
c.Response.ContentType = "text/html; charset=utf-8";
c.Response.Write(outbytes, , outbytes.Length); return Task.FromResult<int>();
} }
3.中间件注册类,代码如下:
/// <summary>
/// 这个类是为AppBuilder添加一个名叫UseMyApp的扩展方法
/// </summary>
public static class MyExtension
{
public static IAppBuilder UseMyApp(this IAppBuilder builder)
{
return builder.Use<MyMiddleware>();
//UseXXX可以带多个参数,对应中间件构造函数中的第2、3、....参数;
}
public static IAppBuilder UseMyApp2(this IAppBuilder builder)
{
return builder.Use<MyMiddleware2>();
//UseXXX可以带多个参数,对应中间件构造函数中的第2、3、....参数;
}
}
用过第三方Owin框架如Nancyfx的朋友是不是感觉比较熟悉,使用UseXXX()
4.注册中间件,新建Startup类
public class Startup
{
public void Configuration(IAppBuilder app)
{ app.UseMyApp(); app.UseMyApp2(); }
}
备注:为了达到演示的目的,必须注意注册时的顺序,我们的Next.Invoke(c)是在MyMiddleware中编写的而不是MyMiddleware2 ,所以必须让MyMiddleware先执行,否则在MyMiddleware2 中遇到return Task.FromResult<int>(0);则直接结束当前请求。当然你也可以更换顺序试试,后面会附上源码下载
5.到目前为止,我们的代码已经写好,配置好TinyFox准备测试,如果不知道Tinyfox作为OwinHost如何调试请参考http://www.cnblogs.com/gaobing/p/4969581.html。
五、测试与总结, 并附上测试图
1.不匹配的url
2.匹配的中间件2的url
3.匹配中间件1的url
备注:之所以不执行中间件2,是因为成功匹配url,所以直接return Task.FromResult<int>(0);结束当前请求
六、源码地址
七、学习交流群
ASP.NET Linux & OWIN QQ 群:468859699
NET & OWIN & VNext QQ 群: 199281001
OWIN系列之自己动手编写中间件的更多相关文章
- OWIN编写中间件
OWIN系列之自己动手编写中间件 一.前言 1.基于OWIN的项目摆脱System.Web束缚脱颖而出,轻量级+跨平台,使得ASP.NET应用程序只需依赖这个抽象接口,不用关心所运行的Web服务器. ...
- 自己动手编写IPv4地址包含关系测试的小脚本
工作中需要对地址包含关系进行测试,现有ipaddress标准库和IPy无法满足,于是自己动手编写小脚本,主要实现== , in, <等专用功能,其他功能可以后续用到再补充,例如迭代打印网段内所有 ...
- 1-自己动手编写ArrayList集合
学习集合的原理,这是一个很简单的代码,没有索引下标越界判断,异常处理等,不够健壮,后面会继续更新完善代码..... 只是入门学习一下 package my; /*** * 自己动手编写一个ArrayL ...
- scrapy进阶-编写中间件和扩展
中间件: 主要讨论的是下载中间件,明确一下顺序: download_middlewares --> server.url ---> spider_middleware 我主 ...
- C#程序集系列01,用记事本编写C#,IL代码,用DOS命令编译程序集,运行程序
本篇主要体验:编写C#,IL代码,用"VS2012开发人员命令提示"编译成程序集,并运行程序. □ C#文件编译为程序集 →在F盘创建as文件夹→在as文件夹下创建MyClass. ...
- 自己动手编写一个VS插件(五)
作者:朱金灿 来源:http://blog.csdn.net/clever101 继续编写VisualStudio插件.这次我编写的插件叫DevAssist(意思是开发助手).在看了前面的文章之后你知 ...
- 循序渐进学.Net Core Web Api开发系列【13】:中间件(Middleware)【有源码】
原文:循序渐进学.Net Core Web Api开发系列[13]:中间件(Middleware) 系列目录 循序渐进学.Net Core Web Api开发系列目录 本系列涉及到的源码下载地址:ht ...
- Linux dts 设备树详解(二) 动手编写设备树dts
Linux dts 设备树详解(一) 基础知识 Linux dts 设备树详解(二) 动手编写设备树dts 文章目录 前言 硬件结构 设备树dts文件 前言 在简单了解概念之后,我们可以开始尝试写一个 ...
- (超详细)动手编写 — 栈、队列 ( Java实现 )
目录 前言 栈 概念 栈的设计 编码实现 小结 队列 概念 队列的设计 编码实现 双端队列 概念 设计 编码 循环队列 循环队列 循环双端队列 声明 前言 栈 概念 什么是栈? **栈 **:是一种特 ...
随机推荐
- (七)Transformation和action详解-Java&Python版Spark
Transformation和action详解 视频教程: 1.优酷 2.YouTube 什么是算子 算子是RDD中定义的函数,可以对RDD中的数据进行转换和操作. 算子分类: 具体: 1.Value ...
- 关于Mysql 触发器
首先,测试版本 Mysql 5.6. 然后再看触发器的语法 CREATE [DEFINER = { user | CURRENT_USER }] TRIGGER trigger_name trigge ...
- spring bean的生命周期
掌握好spring bean的生命周期,对spring的扩展大有帮助. spring bean的生命周期(推荐看) spring bean的生命周期
- css3 text-overflow和white-space,word-wrap,word-break进阶
一.text-overflow 1.text-overflow作用 简单来说,text-overflow用来设置文本溢出时是否用省略标记(...) 准确的说是设置溢出的文本在不显示的情况下怎样展示给用 ...
- BZOJ 2154: Crash的数字表格 [莫比乌斯反演]
2154: Crash的数字表格 Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 2924 Solved: 1091[Submit][Status][ ...
- fixed数据类型
在处理图形运算,特别是3D图形生成运算时,往往要定义一个Fixed数据类型,我称它为定点数,定点数其时就是一个整形数据类型,他的作用就是把所有数 进行转换,从而得到相应类型的整型表达,然后使用定点数进 ...
- 关于类protected、private、public的方法
今天在写代码的时候发现了一种情况,(TP框架)有一个model类 AdminModel.class.php class AdminModel extends Model{ protected $_ ...
- ORA-00054: resource busy and acquire with NOWAIT specified
删除表时遇到 ORA-00054:资源正忙,要求指定NOWAIT 错误.以前在灾备中心遇到过. 资源被锁定了,没有办法删除. 报错日志:ORA-00054: resource busy and acq ...
- LCX端口转发实现内网突破
工具:lcx.exe 原理:当目标主机仅开放了web服务,而该服务又仅能供内网用户使用,外网用户根本无法直接访问.因此想要让外网用户能能够访问局域网中的系统服务,必须进行端口映射等操作才行.其原理就是 ...
- [LeetCode] Delete Duplicate Emails 删除重复邮箱
Write a SQL query to delete all duplicate email entries in a table named Person, keeping only unique ...