一、前言

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. Hibernate 系列 04 - Hibernate 配置相关的类

    引导目录: Hibernate 系列教程 目录 前言: 通过上一篇的增删改查小练习之后,咱们大概已经掌握了Hibernate的基本用法. 我们发现,在调用Hibernate API的过程中,虽然Hib ...

  2. Mysql查询语句使用select.. for update导致的数据库死锁分析

    近期有一个业务需求,多台机器需要同时从Mysql一个表里查询数据并做后续业务逻辑,为了防止多台机器同时拿到一样的数据,每台机器需要在获取时锁住获取数据的数据段,保证多台机器不拿到相同的数据. 我们My ...

  3. memcached安装配置+基础操作

    先安装依赖关系 下载libevent-2.0.21-stable.tar.gz wget https://github.com/downloads/libevent/libevent/libevent ...

  4. ubuntu kylin 14.04安装搜狗输入法

    1.卸载原有的输入法,fcitx或ibus.如卸载fcitx: sudo apt-get remove fcitx*(如不需保留配置文件用purge) sudo apt-get autoremove( ...

  5. vim 在linux下中如何设置显示行数

     在.vimrc(或/etc/vimrc)文件中输入如下文本: set tabstop=4  set softtabstop=4  set shiftwidth=4  set noexpandtab  ...

  6. 第9章 Shell基础(3)_Bash的变量

    4. Bash的变量 4.1 用户自定义变量 4.1.1 什么是变量 变量是计算机的内存单元,其中存放的值可以改变.当Shell脚本需要保存一些信息时,如一个文件名或是一个数字,就把它存放在一个变量中 ...

  7. jmeter解决不同线程组之间传递参数问题

    首先在第一个线程组里讲你需要保存的值放入到jmeter的某个属性中,属性名名字自己定义,如上图的token , props.put("token", token),第二个参数必须是 ...

  8. VPN 部署方案

    VPN 对比: OpenVPN: 客户端连接太麻烦,放弃 PPTP VPN:版本较高的苹果手机没有 PPTP VPN 的连接方式,放弃 L2TP VPN:支持所有平台,客户端连接容易,最终选择部署 L ...

  9. python 高级之面向对象初级

    python 高级之面向对象初级 本节内容 类的创建 类的构造方法 面向对象之封装 面向对象之继承 面向对象之多态 面向对象之成员 property 1.类的创建 面向对象:对函数进行分类和封装,让开 ...

  10. dubbo/dubbox 增加原生thrift及avro支持

    (facebook) thrift / (hadoop) avro / (google) probuf(grpc)是近几年来比较抢眼的高效序列化/rpc框架,dubbo框架虽然有thrift的支持,但 ...