zoukankan      html  css  js  c++  java
  • OWIN编写中间件

    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
    ";
    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!
    ";
    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

  • 相关阅读:
    C# 应用程序性能监测器,很不错的工具
    C#接口(interface)与类(class)的实例互相转换深度解析
    异步与线程深度解析
    内存管理:程序是如何被优雅的装载到内存中
    MacBookM1通过DockerDesk安装MySQL8容器
    理解异步编程体系
    asp.net导入excel方法大集合
    无法激活服务,因为它不支持 ASP.NET 兼容性
    Oracle 数据库 在asp.net中 插入时间
    微软发布更新包 修复SilverLight中的6个问题
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/5077261.html
Copyright © 2011-2022 走看看