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种情况:
- 解答者: 了解问题的内容(Request),给出最终答案(Response),一般不需要后续解答者的参与. 比较典型是解答者是WebApi和StaticFiles(静态文件).
- 参与者: 了解问题的内容,给出一定的资源(Environment)供其他参与者使用,本身一般不参与解答, 有可能在答案中加入一些附加信息.比较典型的有Session和Identity.它们一般会加入一些Cookie但不影响Response实体内容.
- 监控者: 在其他参与者开始处理或者处理完毕的时候对当前的Context中的信息进行处理,它也一般不参与解答,有可能在答案中加入一些附加信息. 比较典型的有Logging, Diagnostics.
如何创建Middleware
创建一个的Middleware分以下几个步骤:
- 引入Microsoft.Owin包
- 建立一个类
- 使这个类继承Microsoft.Owin.OwinMiddleware
- 实现这个类的构造函数
- 覆盖并实现父类的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 = ;
context.Response.Expires = DateTimeOffset.Now;
context.Response.Write(content);
//解答者告诉Server解答已经完毕,后续Middleware不需要处理
return Task.FromResult();
}
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 Middleware
Console.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的运作机制.
OWIN的理解和实践(三) –Middleware开发入门的更多相关文章
- Middleware开发入门
Middleware开发入门 上篇我们谈了Host和Server的建立,但Host和Server无法产出任何有实际意义的内容,真正的内容来自于加载于Server的Middleware,本篇我们就着重介 ...
- OWIN的理解和实践(二) – Host和Server的开发
对于开发人员来说,代码就是最好的文档,如上一篇博文所说,下面我们就会基于Kanata项目的一些具体调用代码,来进一步深入理解OWIN的实现和作用. 今天我们先针对Host和Server来实现一个简单的 ...
- OWIN的理解和实践(一) – 解耦,协作和开放
概述 OWIN的全称是Open Web Interface For .Net, 是MS在VS2013期间引入的全新的概念, 网上已经有不少的关于它的信息, 这里我就谈下我自己的理解: OWIN是一种规 ...
- 20145213《Java程序设计》实验三敏捷开发与XP实践
20145213<Java程序设计>实验三敏捷开发与XP实践 实验要求 1.XP基础 2.XP核心实践 3.相关工具 实验内容 1.敏捷开发与XP 软件工程是把系统的.有序的.可量化的方法 ...
- 20145308刘昊阳 《Java程序设计》实验三 敏捷开发与XP实践 实验报告
20145308刘昊阳 <Java程序设计>实验三 敏捷开发与XP实践 实验报告 实验名称 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 统计的PSP(Personal ...
- 20145215实验三 敏捷开发与XP实践
20145215实验三 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验步骤 (一)敏捷开发与XP 软件工程是把系统的.有序的.可量化的方法应用到软件的开发.运营和维护上的过程.软 ...
- 2018-2019-20175205 实验三敏捷开发与XP实践《Java开发环境的熟悉》实验报告
2018-2019-20175205 实验三敏捷开发与XP实践<Java开发环境的熟悉>实验报告 实验要求 没有Linux基础的同学建议先学习<Linux基础入门(新版)>&l ...
- 20155324 《Java程序设计》实验三 敏捷开发与XP实践
20155324 <Java程序设计>实验三 敏捷开发与XP实践 实验内容 XP基础 1.XP核心实践 2.相关工具 实验步骤 敏捷开发与XP 1.敏捷开发(Agile Developme ...
- 20172328《程序设计与数据结构》实验三 敏捷开发与XP实践报告
20172328<程序设计与数据结构>实验三 敏捷开发与XP实践报告 课程:<程序设计与数据结构> 班级: 1723 姓名: 李馨雨 学号:20172328 实验教师:王志强 ...
随机推荐
- TCP3次握手和4次挥手
为什么握手是3次,挥手是4次? 因为握手的时候,ACK+SYN可以一起发送,而4次挥手是Server端发送对Client的FIN的ACK后不一定会立即断开连接,需要将ACK和FIN分开发送 为什么TI ...
- iOS UITableViewCell的分割线向左延长15(cell长度为全宽)
iOS7情况下: tableView.separatorInset = UIEdgeInsetsZero; iOS8.9情况下: 首先在viewDidLoad方法中加上如下代码: if ([table ...
- WebApi Put方法出现MethodNotAllowed解决方法
WebApi Put方法提交数据的时候总提示MethodNotAllowed,在网上查了很多资料才发现是因为IIS安装了一项服务“WebDAV”,在IIS中把“WebDAV”前面的勾去掉,重新启动电脑 ...
- 一个login
login 1.获取提交表单,保存到变量中.2.判断用户密码是否正确,利用Model类.3.验证用户是否激活.3.判断用户是否记住登录状态,是的话,将其用cookie和session分别保存.没有的话 ...
- js模块和级联
1.模块 模块模式的一般形式是:一个定义了私有变量和函数的函数,利用闭包创建可以访问私有变量和函数的特权函数,最后返回这个特权函数,或者把它们保存到一个可访问的地方.使用模块模式就可以摒弃全局变量的使 ...
- ruby on rails爬坑(三):图片上传及显示
一,问题及思路 最近在用rails + react + mysql基本框架写一个cms + client的项目,里面涉及到了图片的上传及显示,下面简单说说思路,至于这个项目的配置部署,应该会在寒假结束 ...
- ES6中的var let const应如何选择
javascript世界里面的每个人都在说有关ECMAScript 6 (ES6,也称作ES 2015)的话题,对象的巨大变化 ( 类 , super() , 等), 函数 (默认参数等), 以及模块 ...
- 再次完善了 WASPCN for Matlab
前段时间有多个网友询问在64位Matlab中如何使用WASPCN(水和蒸汽性质计算软件)的方法,一直没能给出解决方案. 最近自己有个项目也需要在64位Matlab中如何使用WASPCN(水和蒸汽性质计 ...
- vim的批量注释与删除注释
vim的批量注释与删除注释 方法一:块选择模式 批量注释: Ctrl + v 进入块选择模式,然后移动光标选中你要注释的行,再按大写的I进入行首插入模式输入注释符号如 // 或 #,输入完毕之后,Vi ...
- hdu 5795
A Simple Nim Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tota ...