一、前言

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系列之自己动手编写中间件的更多相关文章

  1. OWIN编写中间件

    OWIN系列之自己动手编写中间件 一.前言 1.基于OWIN的项目摆脱System.Web束缚脱颖而出,轻量级+跨平台,使得ASP.NET应用程序只需依赖这个抽象接口,不用关心所运行的Web服务器. ...

  2. 自己动手编写IPv4地址包含关系测试的小脚本

    工作中需要对地址包含关系进行测试,现有ipaddress标准库和IPy无法满足,于是自己动手编写小脚本,主要实现== , in, <等专用功能,其他功能可以后续用到再补充,例如迭代打印网段内所有 ...

  3. 1-自己动手编写ArrayList集合

    学习集合的原理,这是一个很简单的代码,没有索引下标越界判断,异常处理等,不够健壮,后面会继续更新完善代码..... 只是入门学习一下 package my; /*** * 自己动手编写一个ArrayL ...

  4. scrapy进阶-编写中间件和扩展

    中间件: 主要讨论的是下载中间件,明确一下顺序: download_middlewares   -->   server.url    --->  spider_middleware 我主 ...

  5. C#程序集系列01,用记事本编写C#,IL代码,用DOS命令编译程序集,运行程序

    本篇主要体验:编写C#,IL代码,用"VS2012开发人员命令提示"编译成程序集,并运行程序. □ C#文件编译为程序集 →在F盘创建as文件夹→在as文件夹下创建MyClass. ...

  6. 自己动手编写一个VS插件(五)

    作者:朱金灿 来源:http://blog.csdn.net/clever101 继续编写VisualStudio插件.这次我编写的插件叫DevAssist(意思是开发助手).在看了前面的文章之后你知 ...

  7. 循序渐进学.Net Core Web Api开发系列【13】:中间件(Middleware)【有源码】

    原文:循序渐进学.Net Core Web Api开发系列[13]:中间件(Middleware) 系列目录 循序渐进学.Net Core Web Api开发系列目录 本系列涉及到的源码下载地址:ht ...

  8. Linux dts 设备树详解(二) 动手编写设备树dts

    Linux dts 设备树详解(一) 基础知识 Linux dts 设备树详解(二) 动手编写设备树dts 文章目录 前言 硬件结构 设备树dts文件 前言 在简单了解概念之后,我们可以开始尝试写一个 ...

  9. (超详细)动手编写 — 栈、队列 ( Java实现 )

    目录 前言 栈 概念 栈的设计 编码实现 小结 队列 概念 队列的设计 编码实现 双端队列 概念 设计 编码 循环队列 循环队列 循环双端队列 声明 前言 栈 概念 什么是栈? **栈 **:是一种特 ...

随机推荐

  1. JS原型链

    JS作为发展了多年了对象语言,支持继承,和完全面向对象语言不同的是,JS依赖原型链来实现对象的继承. 首先JS的对象分两大类,函数对象和普通对象,每个对象均内置__proto__属性,在不人为赋值__ ...

  2. php-into 安装时遇到的各种问题,php -m跟phpinfo()显示不一致

    系统环境 阿里云服务器 ubuntu nginx php5.4.23 在Yii2中格式显示用户currency,所以需要intl模块,没啥说的装吧. apt-get install libicu-de ...

  3. Spark作业调度阶段分析

    Spark作为分布式的大数据处理框架必然或涉及到大量的作业调度,如果能够理解Spark中的调度对我们编写或优化Spark程序都是有很大帮助的: 在Spark中存在转换操作(Transformation ...

  4. RHEL6和RHEL7恢复root用户密码

    一.RHEL6恢复root密码 将系统重启,出现如下界面按上下键选择会停住,并输入e键 选中下图红框选项,再输入e键 再输入1,进入单用户模式 输入b进行启动   修改密码,然后重启 二.RHEL7恢 ...

  5. RabbitMq 集群搭建

        实验环境: 操作系统为 Centos 7.2 IP hostName 192.168.190.132 node132 192.168.190.139 node139 192.168.190.1 ...

  6. WORD中字数和字符

    在WORD中,一个汉字算1个字符,也算是1个字,一个标点符号也算1个字符,也算是1个字,WORD中字符数的统计分为(不计空格)和(计空格)的两种. 如果一篇文章仅由汉字和标点符号组成,那么字数=字符数 ...

  7. HDOJ 1051. Wooden Sticks 贪心 结构体排序

    Wooden Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  8. Lambert(朗伯)光照模型 和Half Lambert的区别

    Lambert-它不包括任何任何镜面属性,对粗糙物体来说,这项属性是非常有用的,它不会反射出周围的环境.Lambert材质可以是透明的,在光线追踪渲染中发生折射,但是如果没有镜面属性,该类型就不会发生 ...

  9. [No000094]SVN学习笔记4-版本库概念与部分日常操作

    基本概念 版本库 Subversion 使用集中的数据库,它包含了所有的版本控制文件及其完整历史.这个数据库就是版本库.版本库通常位于运行 Subversion 服务器的文件服务器上,向 Subver ...

  10. [No000091]SVN学习笔记2-TortoiseSVN Client初级操作update(获取)、commit(提交)

    SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成很多不同的版本,这就需要程序员有效的管理代码,在需要的时候可以迅速,准确取出相应的版本. Subversion是什么? ...