一、前言

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. 在DBeaver中phoenix查询报错:org.apache.phoenix.exception.PhoenixIOException: The system cannot find the path specified

    环境:Phoenix:4.4,win7系统 问题:Phoenix在查询hbase时,报"系统找不到指定路径". 解决: 请参见 https://distcp.quora.com/C ...

  2. Tomcat 服务应用

    转自:http://wiki.jikexueyuan.com/project/tomcat/windows-service.html Tomcat8 是一个服务应用,能使 Tomcat 8 以 Win ...

  3. Fedora javac 命令提示 [javac: 未找到命令...]

    [joy@localhost ~]$ java -version openjdk version "1.8.0_91" OpenJDK Runtime Environment (b ...

  4. Dijkstra算法(三)之 Java详解

    http://www.cnblogs.com/skywang12345/p/3711516.html

  5. 好用的dos命令

    控制台使用"help"查看帮助,使用"help + command-name"或"command-name /?"查看命令帮助. dir 可 ...

  6. sql2008“备份集中的数据库备份与现有的xx数据库不同”解决方法

    http://www.cnblogs.com/huangfr/archive/2012/08/09/2629687.html 因为是在另一台电脑对同名数据库做的备份,用常规方法还原,提示不是相同数据库 ...

  7. ngx_http_core_module模块.md

    Directives aio Syntax: aio on | off | threads[=pool]; Default: aio off; Context: http, server, locat ...

  8. django ORM的外键操作

    外键约束示例 #models操作如下 class HostInfo(models.Model): servername = models.CharField(max_length=) serverip ...

  9. docker学习(8) 在mac机上搭建私有仓库

    docker的私有仓库类似maven的私服,一般用于公司内部搭建一个类似docker hub的环境,这样上传.下载镜像速度较快,本文将演示如何在mac上利用docker-machine搭建无需SSL证 ...

  10. [LeetCode] Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字

    Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Find the maximum re ...