一、前言

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. ASP.NET MVC Controllers and Actions

    MVC应用程序里的URL请求是通过控制器Controller处理的,不管是请求视图页面的GET请求,还是传递数据到服务端处理的Post请求都是通过Controller来处理的,先看一个简单的Contr ...

  2. 封装系统(以封装Windows 7为例)

    安装步骤: 1.安装系统 2.启用Administrator帐户 3.进行简单的系统设置 4.系统精简 5.安装Adobe Flash Player 6.设置IE主页 7.在系统盘(C盘)创建Sysp ...

  3. kvm/qemu/libvirt学习笔记 (1) qemu/kvm/libvirt介绍及虚拟化环境的安装

    kvm简介 kvm最初由Quramnet公司开发,2008年被RedHat公司收购.kvm全称基于内核的虚拟机(Kernel-based Virtual Machine),它是Linux的一个内核模块 ...

  4. [django]手动数据库备份

    基本原理是按钮点击后,系统查询出数据表中信息,然后在网页中导出相关表格! 若有自动数据库备份的兄弟,指点一下! 模板代码: <a href="{% url 'work_backup' ...

  5. JS--浏览器兼容之new Date

    Js 中有一个Date属性. 我们可以通过new Date(formatString) 来生命日期. 不过生命日期里面有一个坑就是. new Date('2016-05-13'), Chrome 和 ...

  6. python爬虫学习(8) —— 关于4399的一个小Demo

    堂弟喜欢各种游戏,在没有网络的情况下,上4399显得很无力. 另外,4399广告好多,,而且加载慢.. 怎么办,,写个爬虫吧,,把4399上的"好玩"游戏爬下来. 1. 分析阶段 ...

  7. Qt 开启鼠标跟踪,自动激活mouseMoveEvent的问题

    最近在Qt上实现一个功能,鼠标在图片上移动,触发mouseMoveEvent事件,进而生成一个小的半透明窗口,放大显示以鼠标为中心的一个区域的图像并随鼠标移动.但是,必须鼠标摁下,才触发mouseMo ...

  8. [LeetCode] Delete Node in a BST 删除二叉搜索树中的节点

    Given a root node reference of a BST and a key, delete the node with the given key in the BST. Retur ...

  9. [LeetCode] Contains Duplicate II 包含重复值之二

    Given an array of integers and an integer k, return true if and only if there are two distinct indic ...

  10. C#进阶系列——WebApi 接口测试工具:WebApiTestClient

    前言:这两天在整WebApi的服务,由于调用方是Android客户端,Android开发人员也不懂C#语法,API里面的接口也不能直接给他们看,没办法,只有整个详细一点的文档呗.由于接口个数有点多,每 ...