zoukankan      html  css  js  c++  java
  • Owin中间件动手做

    摘要:本文目的是了解Owin基本原理。讲述如何从控制台创建一个自宿主的OwinHost,然后再编写一两个中间件

    准备工作

    首先通过VisualStudio创建一个控制台应用

    然后添加Owin的Nuget包引用

    需要的包如下

    Owin
    Microsoft.Owin
    Microsoft.Owin.Hosting
    Microsoft.Owin.Host.HttpListener
    

    准备工作到此结束

    编写OwinStartup类

    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.Run(HandleRequest);
        }
        static Task HandleRequest(IOwinContext context)
        {
            context.Response.ContentType = "text/plain";
            return context.Response.WriteAsync("Hello world from myOwin");
        }
    }
    

    当OwinHost运行时,会首先加载Startup类,Configuration方法是必须有的,在Configuration方法中向Owin管道插入中间件,所有的请求都是中间件处理。

    在这个Configurationapp.Run(HandleRequest);方法的作用是向管道中添加一个没有后续中间件的中间件,一般来讲一个Owin管道中有许多中间件,不同的中间件处理不同的事情,在处理结束后选择性的调用后面的中间件,例如某个身份验证中间件可以在验证失败时结束请求。而app.Run方法就是插如一个没有后续事项的中间件。稍后我们会编写常规的中间件。

    这个中间件做的事很简单,就是向响应写入一个字符串,无论请求是什么结果都是一样的。

    在Main方法中启动Host

    static void Main(string[] args)
    {
        var url = "http://localhost:8080/";
        var opt = new StartOptions(url);
    
        using (WebApp.Start<Startup>(opt))
        {
            Console.WriteLine("Server run at " + url + " , press Enter to exit.");
            Console.ReadLine();
        }
    }
    

    StartOptions类用来指定一些启动参数,最少应该指定一个url,这里一并指定了使用8080端口

    启动程序控制台输出如下

    Server run at http://localhost:8080/ , press Enter to exit.
    

    用浏览器打开 http://localhost:8080/
    效果如下:

    `Hello world from myOwin`
    

    尝试更改路径你得到的始终是一个结果
    你可以尝试将Configuration中的代码注释掉,在运行程序,这是访问将得到空页面,Http代码也将是404,因为Owin管道中没有中间件处理请求。

    编写中间件

    我们编写一个名为Ding的中间件

    public class DingMiddleware : OwinMiddleware
    {
        public DingMiddleware(OwinMiddleware next) : base(next)
        {
        }
    
        public override Task Invoke(IOwinContext context)
        {
            if (context.Request.Path.Value.Equals("/home/index"))
            {
                context.Response.Write("hello world from home/index");
            }
            if (Next != null)
            {
                return Next.Invoke(context);
            }
            return Task.CompletedTask;
        }
    }
    

    这个中间件在检测到访问路径是/home/index时向Response中写入一句话,然后检测是否有下一个中间件,如果有就调用。

    添加中间件到Configuration

    可以直接在Configuration中加入app.Use<DingMiddleware>()来插入中间件,但是我们一般使用扩展方法来做这件事。

    public static class MyMidlewareExtention
    {
        public static IAppBuilder UseDing(this IAppBuilder app)
        {
            return app.Use<DingMiddleware>();
        }
    }
    

    修改Configuration中的代码:

    public void Configuration(IAppBuilder app)
    {
        app.UseDing();
        app.Run(HandleRequest);
    }
    

    现在管道中有两个中间件了,现在运行程序,在地址栏中输入http://localhost:8080/home/index将得到如下结果
    hello world from home/indexHello world from myOwin
    因为Ding中间件在处理之后继续调用了接下来的中间件
    输入其他路径将得到Hello world from myOwin这个结果

    如果将Configuration中的两个中间件位置调换,的到的结果只有一个Hello world from myOwin,因为app.Run(HandleRequest);不执行后续的中间件。

    第二个中间件

    public class DiDiDiMiddleware : OwinMiddleware
    {
        public DiDiDiMiddleware(OwinMiddleware next) : base(next)
        {
        }
    
        public override Task Invoke(IOwinContext context)
        {
            if (context.Request.QueryString.Value == "boom")
            {
    			context.Response.Write("Boom! Boom! Boom!");
                return Task.CompletedTask;
            }
            if (Next != null)
            {
                return Next.Invoke(context);
            }
            return Task.CompletedTask;
        }
    }
    

    这个中间件在地址栏QueryString(?后边的部分)等于boom时结束请求。

    MyMidlewareExtention代码修改如下:

    public static class MyMidlewareExtention
    {
        public static IAppBuilder UseDing(this IAppBuilder app)
        {
            return app.Use<DingMiddleware>();
        }
        public static IAppBuilder UseDiDiDi(this IAppBuilder app)
        {
            return app.Use<DiDiDiMiddleware>();
        }
    }
    

    Startup类修改如下:

    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
    
            app.UseDiDiDi();
            app.UseDing();
        }
    }
    

    这里去掉了app.Run此时,对于非/home/index的请求会得到404,所以我们暂时改动下代码将HandleRequest方法封装成一个默认的中间件

    代码改动如下:

    public class DefaultMiddleware : OwinMiddleware
    {
        public DefaultMiddleware(OwinMiddleware next) : base(next)
        {
        }
    
        public override Task Invoke(IOwinContext context)
        {
            var path = context.Request.Path.Value;
            context.Response.Write($"hey you come from {path}!");
            return Task.CompletedTask;
        }
    }
    

    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseDiDiDi();
            app.UseDing();
            app.UseDefault();
        }
    }
    

    运行程序观察结果是否符合预期。
    当地址中含有?boom时会的到一个Boom!Boom!Boom!

    总结:Owin的管道概念其实简单易懂,在程序启动之前,向里面插入中间件,中间件决定请求是否继续向下走。在管道中的中间件可以拿到请求的所有信息以对请求进行处理,管道里的中间件执行结束之后,这个请求就被处理完成了,然后发回浏览器。

  • 相关阅读:
    通讯录封装实现
    简单通讯录的实现 main..h .m文件全部
    iOS 开发 OC编程 字典和集合 排序方法
    iOS 开发 OC编程 数组冒泡排序.图书管理
    iOS 开发 OC编程 属性和字符串练习
    iOS 开发 OC编程 属性和字符串
    iOS 开发 OC编程 便利构造器以及初始化方法
    iOS 开发 OC编程 方法的书写
    IOS 开发 OC编程 类和对象
    iOS 开发 c语言阶段考试题
  • 原文地址:https://www.cnblogs.com/rocketRobin/p/7844423.html
Copyright © 2011-2022 走看看