原文:OWIN的理解和实践(三) –Middleware开发入门

上篇我们谈了Host和Server的建立,但Host和Server无法产出任何有实际意义的内容,真正的内容来自于加载于Server的Middleware,本篇我们就着重介绍下Middleware的开发入门.

Middleware是什么

如果把HTTP交互理解为一次答题活动,那么Request是问题,Response就是答案,Server是课堂,Middleware就是参与者,注意我这里用的是参与而不是解答,因为我们允许有些Middleware不给出答案.

Middleware有什么资源

要参与答题活动就必须有知识,也就是资源.在OWIN规则中,所有Middleware只能获得并影响一个资源,这个就是OWIN Context,有一个Microsoft.Owin. IOwinContext接口定义了这个上下文的标准. 我们来看下这个里面有什么东西.

这个上下文接口中 提供的资源,是Middleware进行运作的关键:

  • Authentication : 获取可在当前请求上使用的身份验证(Identity)中间件功能。通过这个属性可以非常便捷在任何Middleware中访问当前的Identity信息.当然至少一个Identity中间件需要被加载,否则这个属性中的内容没有意义.
  • Environment: 获取已包装的 OWIN 环境。它本质是一个数据字典,一个Middleware利用Key放入一个信息,而另外一个Middleware根据Key拿出来使用. 和Session异曲同工.
  • Request: 获取可公开特定于请求的属性的包装。Middleware从这里了解我们的提问者(Request)提供了那些信息.
  • Response : 获取可公开特定于响应的属性的包装。Middleware通过这个属性可以给出,影响或者改变我们的Response(答案),当然它也可以不做任何调整.

Middleware到底做什么,怎么做

简单来说,Middleware可以做什么怎么做可以归结为以下几点:

  • 获得OWIN Context和它内部封装的所有信息.
  • 从Request中获取请求的所有信息.
  • 从Environment中获取其他Middleware共享的资源,以便于和其他Middleware交互,或者使用其他Middleware提供的功能.
  • 从Authentication中获取当前的身份验证信息和结果.
  • 通过Response给出,影响,甚至改变Server即将发出的”答案”

Middleware有哪几种类型

刚刚我们说了,Middleware不一定是问题的解答者, 他们有前后的顺序和各自回答问题的方式,根据他们的参与方式,我把他们分成3种情况:

  1. 解答者: 了解问题的内容(Request),给出最终答案(Response),一般不需要后续解答者的参与. 比较典型是解答者是WebApi和StaticFiles(静态文件).
  2. 参与者: 了解问题的内容,给出一定的资源(Environment)供其他参与者使用,本身一般不参与解答, 有可能在答案中加入一些附加信息.比较典型的有Session和Identity.它们一般会加入一些Cookie但不影响Response实体内容.
  3. 监控者: 在其他参与者开始处理或者处理完毕的时候对当前的Context中的信息进行处理,它也一般不参与解答,有可能在答案中加入一些附加信息. 比较典型的有Logging, Diagnostics.

如何创建Middleware

创建一个的Middleware分以下几个步骤:

  1. 引入Microsoft.Owin包
  2. 建立一个类
  3. 使这个类继承Microsoft.Owin.OwinMiddleware
  4. 实现这个类的构造函数
  5. 覆盖并实现父类的Invoke函数

一个最为典型的实现如下

    using Microsoft.Owin;using System.Threading.Tasks;/// <summary>/// Middleware类必须继承Microsoft.Owin.OwinMiddleware/// </summary>public class SampleMiddleware : OwinMiddleware{public SampleMiddleware(OwinMiddleware next): base(next){//构造函数
        }public override Task Invoke(IOwinContext context){//中间件的实现代码return Next.Invoke(context);}
}

绝大部分Middleware需要预设一些属性,这些属性可以通过改造构造函数来实现:

        object m_Options;public SampleMiddleware(OwinMiddleware next,object options): base(next){//引入参数类,并可以再类中使用m_Options = options;}

当然类似的options参数可以有多个.

以上的Middleware实现其实是没有意义的,因为没有做任何事情,下面我将给出一个”给出答案”的简单实现,根据上面的描述,我在下面仅仅给出Invoke函数的内容.

这里再插一句,上述代码中的next或Next指的是排在这个Middleware之后的另一个Middleware,而context就是我们上面所说的上下文信息.

一个简单的Middleware范例

剩下的工作,就是在Invoke函数中实现当前Middleware的功能,这里给出一个非常简单的实现,来做出一个最简单的功能: 输入结尾为\tick的URL,返回一个纯文本的Response,里面包含当前服务器时间的Tick信息.

       public override Task Invoke(IOwinContext context){PathString tickPath = new PathString("/tick");//判断Request路径为/tick开头if (context.Request.Path.StartsWithSegments(tickPath)){string content = DateTime.Now.Ticks.ToString();//输出答案--当前的Tick数字context.Response.ContentType = "text/plain";context.Response.ContentLength = content.Length;context.Response.StatusCode = 200;context.Response.Expires = DateTimeOffset.Now;context.Response.Write(content);//解答者告诉Server解答已经完毕,后续Middleware不需要处理return Task.FromResult(0);}else//如果不是/tick路径,那么交付后续Middleware处理return Next.Invoke(context);}

这里提几个要点:

  • PathString是Miscrosoft.Owin下一个类,封装了URL处理的一些功能.
  • Task.FromResult(0) 表示一个空的Task,说明该Middleware在某些情况下不再触发后续的Middleware运行—也就是”到此为止”.
  • 最后Next.Invoke(context)是一个非常标准的实现,把上下文交付下一个Middleware继续处理—相当于”交出接力棒”.
  • 这个Middleware是一个标准的解答者.它给出了”/tick”这个问题的最终答案.

如何使用Middleware

这里需要回到我的上一篇博文, Host和Server开发, 在那里面,我说到目前的Startup函数是空的,说明没有加载任何Middleware,而现在我们需要在那个函数里面加载我们开发的Middleware了,代码很简单:

        private static void Startup(Owin.IAppBuilder app){//加载Sample MiddlewareConsole.WriteLine("Sample Middleware loaded...");app.Use<SampleMiddleware>();}

注意2点:

  • 保证已经加入了 using Owin;
  • SampleMiddleware的构造函数是仅有一个OwinMiddleware参数的版本,如果有附加参数,请加到Use函数的参数列表里面去.

好了,联合上一篇博文的代码,编译运行.我们能够看到如下输出界面:

(注意:很多机器需要管理员权限运行VS,才能正常运行该程序)

打开浏览器,访问http://localhost:9000/tick

我们看到了一个tick. 这就是这个中间件返回的结果.而其他地址依然会没有任何返回,这是因为并没有任何其他Middleware来处理其他的情况.

当然,基于OWIN架设的体系,我们可以开发更加复杂的Middleware,下一篇,我将会进一步给出三个比较复杂的Middleware实现:  StaticFile, Session, Logging; 来帮助大家进一步理解,解答者,参与者和监控者的概念.同时也深入理解Middleware的运作机制.

转载于:https://www.cnblogs.com/owenzh/p/11167965.html

OWIN的理解和实践(三) –Middleware开发入门相关推荐

  1. OWIN的理解和实践(二) – Host和Server的开发

    对于开发人员来说,代码就是最好的文档,如上一篇博文所说,下面我们就会基于Kanata项目的一些具体调用代码,来进一步深入理解OWIN的实现和作用. 今天我们先针对Host和Server来实现一个简单的 ...

  2. 20155229实验三 《Java面向对象程序设计实验三 敏捷开发与XP实践 》实验报告

    实验题目 1.在IDEA中使用工具(Code->Reformate Code)把下面代码重新格式化,再研究一下Code菜单,找出一项让自己感觉最好用的功能. 2.下载搭档实验二的Complex代 ...

  3. 20155314 2016-2017-2 《Java程序设计》实验三 敏捷开发与XP实践

    20155314 2016-2017-2 <Java程序设计>实验三 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验知识点总结 (一)敏捷开发与XP 软件工程:把系统 ...

  4. 20145326蔡馨熠 实验三 敏捷开发与XP实践

    20145326蔡馨熠 实验三 "敏捷开发与XP实践" 程序设计过程 一.实验内容 使用 git 上传代码 使用 git 相互更改代码 实现代码的重载 1.git上传代码 首先我通 ...

  5. 20155231 实验三 敏捷开发与XP实践

    20155231 实验三 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验要求 没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑器&g ...

  6. 20155220 实验三 敏捷开发与XP实践 实验报告

    20155220 实验三 敏捷开发与XP实践 实验报告 实验内容 XP基础 XP核心实践 相关工具 实验要求 没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim ...

  7. 20165205 2017-2018-2 《Java程序设计》实验三 敏捷开发与XP实践

    20165205 2017-2018-2 <Java程序设计>实验三 敏捷开发与XP实践 20165205 2017-2018-2 <Java程序设计>实验三 敏捷开发与XP实 ...

  8. 20155226 实验三 敏捷开发与XP实践 实验报告

    20155226 实验三 敏捷开发与XP实践 实验报告 实验内容 XP基础 XP核心实践 相关工具 实验要求 没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim ...

  9. 20175212童皓桢 实验三敏捷开发与XP实践实验报告

    20175212童皓桢 实验三敏捷开发与XP实践实验报告 实验内容 XP基础 XP核心实践 相关工具 实验步骤 一.Code菜单功能的研究 Move Line/statement Down/Up:将某 ...

最新文章

  1. Android app被系统kill的场景
  2. Java8 - 使用工厂方法 supplyAsync创建 CompletableFuture
  3. pdf2swf无法转换某些文档,提示缺少字体时的处理
  4. AutoMapper在MVC中的运用小结
  5. 无条件跳转页面的代码
  6. KubeVela 上手(1)|让云端应用交付更加丝滑
  7. 计算机科技英语论文,计算机专业英语(第2版)——科技交流与科技论文写作
  8. 工资10000元,应该交多少税?
  9. WinForm 的dataGridView全选,反选
  10. antv g2字体阴影_antv/G2 v4使用遇坑之旅
  11. 修改刷新没反应_【原神】全特产高效率采集线路和刷新时间
  12. 搜索RaySource资源的8大方法
  13. 后端代码增删改查的编写~
  14. C#中接口IFormattable/IFormatProvider/ICustomFormatter的区别与用法
  15. Android 腾讯Bugly热更新笔记
  16. STM32——用PWM控制电机
  17. 机房收费管理系统之退卡
  18. 20系列和30系列显卡下的tensorflow-gpu环境配置,避坑指南
  19. 美国医生推荐感冒食疗方
  20. 软件开发的12大定律,你是否使用了呢

热门文章

  1. UE3客户端加入DS过程
  2. 关于CI的服务器与最佳实践,这里有一些思考 1
  3. Idea快速生成War包
  4. [实战]MVC5+EF6+MySql企业网盘实战(15)——逻辑重构2
  5. C#有关Session 操作的几个误区【转】
  6. pycharm和vs code的使用体验
  7. 快速编辑 Shell 命令行
  8. JavaFX FileChooser文件选择器,缓存上一次打开的目录
  9. XebiaLabs DevOps平台推出软件发布风险和合规性管理功能
  10. re:Invent解读:没想到你是这样的AWS