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调用不同的处理方法

 1     /// <summary>
2 /// OWIN "中间件" - MyMiddleware
3 /// </summary>
4 public class MyMiddleware : OwinMiddleware
5 {
6
7
8 /// <summary>
9 /// 构造函数,第一个参数必须为 OwinMiddleware对象 ;第一个参数是固定的,后边还可以添加自定义的其它参数
10 /// </summary>
11 /// <param name="next">下一个中间件</param>
12 public MyMiddleware(OwinMiddleware next)
13 : base(next)
14 {
15
16 }
17
18
19 /// <summary>
20 /// 处理用户请求的具体方法,该方法是必须的
21 /// </summary>
22 /// <param name="c">OwinContext对象</param>
23 /// <returns></returns>
24 public override Task Invoke(IOwinContext c)
25 {
26 if (Next != null && c.Request.Path.Value != "/home/index")
27 {
28
29 var message1 = "NotFound\r\n";
30 var outbytes1 = Encoding.UTF8.GetBytes(message1);
31 c.Response.ContentType = "text/html; charset=utf-8";
32 c.Response.Write(outbytes1, 0, outbytes1.Length);
33 return Next.Invoke(c);
34 }
35
36 // var urlPath = c.Request.Path;
37 // switch (urlPath) {
38 // ..........
39 // ..........
40 // 可以根据不同的URL PATH调用不同的处理方法
41 // 从而构成一个完整的应用。
42 // }
43
44
45 var message = "Welcome to My Home!";
46 var outbytes = Encoding.UTF8.GetBytes(message);
47 c.Response.ContentType = "text/html; charset=utf-8";
48 c.Response.Write(outbytes, 0, outbytes.Length);
49
50 return Task.FromResult<int>(0);
51 }
52
53
54
55 }

介绍:

1.构造函数第一个参数必须为 OwinMiddleware对象,可从Microsoft.Owin.dll源码得知,这里不作话题。

2.我们在上面提到了“如果当前中间件无法匹配请求则会将请求转向下一个中间件处理”,上面的代码中的if如果成立,执行returnNext.Invoke(c);后会找注册的下一个中间件,如果url匹配,会正确执行,并且执行return Task.FromResult<int>(0);结束当前请求。

2.新建类MyMiddleware2继承OwinMiddleware并且实现Invoke函数,之所以建立两个中间件,是为了演示”如果当前中间件无法匹配请求则会将请求转向下一个中间件处理",同样附上代码

 1     /// <summary>
2 /// OWIN "中间件" - MyMiddleware2
3 /// </summary>
4 public class MyMiddleware2 : OwinMiddleware
5 {
6
7
8 /// <summary>
9 /// 构造函数,第一个参数必须为 OwinMiddleware对象 ;第一个参数是固定的,后边还可以添加自定义的其它参数
10 /// </summary>
11 /// <param name="next">下一个中间件</param>
12 public MyMiddleware2(OwinMiddleware next)
13 : base(next)
14 {
15 }
16
17
18 /// <summary>
19 /// 处理用户请求的具体方法,该方法是必须的
20 /// </summary>
21 /// <param name="c">OwinContext对象</param>
22 /// <returns></returns>
23 public override Task Invoke(IOwinContext c)
24 {
25
26 if (Next != null && c.Request.Path.Value != "/user")
27 {
28
29 var message1 = "NotFound2!\r\n";
30 var outbytes1 = Encoding.UTF8.GetBytes(message1);
31 c.Response.ContentType = "text/html; charset=utf-8";
32 c.Response.Write(outbytes1, 0, outbytes1.Length);
33 return Task.FromResult(0);
34 }
35
36 // var urlPath = c.Request.Path;
37 // switch (urlPath) {
38 // ..........
39 // ..........
40 // 可以根据不同的URL PATH调用不同的处理方法
41 // 从而构成一个完整的应用。
42 // }
43
44
45 var message = "I'm MyMiddleware2";
46 var outbytes = Encoding.UTF8.GetBytes(message);
47 c.Response.ContentType = "text/html; charset=utf-8";
48 c.Response.Write(outbytes, 0, outbytes.Length);
49
50 return Task.FromResult<int>(0);
51 }
52
53
54
55 }

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类

 1   public class Startup
2 {
3 public void Configuration(IAppBuilder app)
4 {
5
6 app.UseMyApp();
7
8 app.UseMyApp2();
9
10 }
11 }

备注:为了达到演示的目的,必须注意注册时的顺序,我们的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

作者: jamesbing

OWIN编写中间件的更多相关文章

  1. OWIN系列之自己动手编写中间件

    一.前言 1.基于OWIN的项目摆脱System.Web束缚脱颖而出,轻量级+跨平台,使得ASP.NET应用程序只需依赖这个抽象接口,不用关心所运行的Web服务器. 2.OWIN.dll介绍 使用反编 ...

  2. Owin 自定义中间件(2)中间件进阶

    前面一篇文章简单的介绍了中间件的应用 下面编写一个自定义的中间件类库,并加入中间件参数以及引入日志记录中间件的异常 下面来看下中间件的构造,参数可以自定义 这里我定义了一个参数类 编写中间件需要引入 ...

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

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

  4. Owin 自定义中间件

    /// <summary> /// 自定义的中间件 /// </summary> public class CustomMiddleware : OwinMiddleware ...

  5. Owin中间件动手玩

    摘要:本文目的是了解Owin基本原理.讲述如何从控制台创建一个自宿主的OwinHost,然后再编写一两个中间件 准备工作 首先通过VisualStudio创建一个控制台应用 然后添加Owin的Nuge ...

  6. Owin中间件动手做

    摘要:本文目的是了解Owin基本原理.讲述如何从控制台创建一个自宿主的OwinHost,然后再编写一两个中间件 准备工作 首先通过VisualStudio创建一个控制台应用 然后添加Owin的Nuge ...

  7. 使用Owin中间件搭建OAuth2.0认证授权服务器

    前言 这里主要总结下本人最近半个月关于搭建OAuth2.0服务器工作的经验.至于为何需要OAuth2.0.为何是Owin.什么是Owin等问题,不再赘述.我假定读者是使用Asp.Net,并需要搭建OA ...

  8. [2014-11-11]使用Owin中间件搭建OAuth2.0认证授权服务器

    前言 这里主要总结下本人最近半个月关于搭建OAuth2.0服务器工作的经验.至于为何需要OAuth2.0.为何是Owin.什么是Owin等问题,不再赘述.我假定读者是使用Asp.Net,并需要搭建OA ...

  9. 我怎么忽略了身份框架魔法,只是使用OWIN验证的中间件,以获得要求我寻求什么呢?

    该OWIN中间件的东西第三方登录集成到您的ASP.NET应用程序是非常酷的,但我似乎无法弄清楚如何就剜出来的新的ID,它取代了蹩脚的成员身份 API.我没有兴趣在坚持所产生的债权,并在英法为基础的数据 ...

随机推荐

  1. FreeSwitch安装和配置记录

    安装FreeSwitch 主要示例,下面的命令: git clone -b v1.2.stable git://git.freeswitch.org/freeswitch.git cd freeswi ...

  2. Android Studio Gradle 添加.so 支持文件

    近期发展Android Wear 关注商品.官员Demo所有gradle 工程. 当然,我也用eclipse配置一个可行的环境. 问题来了,eclipse,android studio 开发 andr ...

  3. poj 2769 Reduced ID Numbers(memset使用技巧)

    Description T. Chur teaches various groups of students at university U. Every U-student has a unique ...

  4. xcode target

    A target specifies a product to build and contains the instructions for building the product from a ...

  5. 服务器编程入门(4)Linux网络编程基础API

      问题聚焦:     这节介绍的不仅是网络编程的几个API     更重要的是,探讨了Linux网络编程基础API与内核中TCP/IP协议族之间的关系.     这节主要介绍三个方面的内容:套接字( ...

  6. 【译】ASP.NET MVC 5 教程 - 10:添加验证

    原文:[译]ASP.NET MVC 5 教程 - 10:添加验证 在本节中,我们将为Movie模型添加验证逻辑,并确认验证规则在用户试图使用程序创建和编辑电影时有效. DRY 原则 ASP.NET M ...

  7. Python的Tkinter将窗口置顶

    root = Tk()root.wm_attributes('-topmost',1)

  8. 关于margin-right的应用问题

    今天在群里面,有人抛出了一个关于css中margin-right没有效果的问题.CSS代码和HTML代码例如以下: .style1{ width:400px; height:440px; backgr ...

  9. XSS漏洞的分类

    XSS漏洞依照攻击利用手法的不同,有下面三种类型: 类型A,本地利用漏洞,这样的漏洞存在于页面中client脚本自身.其攻击步骤例如以下所看到的: Alice给Bob发送一个恶意构造了Web的URL. ...

  10. VC中Tab control的用法

    1. 新建一个MFC工程, 取名MyTab, 选择Dialog based, 然后Finish. 2. 删除对话框上默认添加的三个控件. 添加Tab Control控件并在Property属性中设置I ...