本文共 4192 字,大约阅读时间需要 13 分钟。
摘要:本文目的是了解Owin基本原理。讲述如何从控制台创建一个自宿主的OwinHost,然后再编写一两个中间件
首先通过VisualStudio创建一个控制台应用
然后添加Owin的Nuget包引用
需要的包如下
OwinMicrosoft.OwinMicrosoft.Owin.HostingMicrosoft.Owin.Host.HttpListener
准备工作到此结束
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管道插入中间件,所有的请求都是中间件处理。
在这个Configuration
中app.Run(HandleRequest);
方法的作用是向管道中添加一个没有后续中间件的中间件,一般来讲一个Owin管道中有许多中间件,不同的中间件处理不同的事情,在处理结束后选择性的调用后面的中间件,例如某个身份验证中间件可以在验证失败时结束请求。而app.Run
方法就是插如一个没有后续事项的中间件。稍后我们会编写常规的中间件。
这个中间件做的事很简单,就是向响应写入一个字符串,无论请求是什么结果都是一样的。
static void Main(string[] args){ var url = "http://localhost:8080/"; var opt = new StartOptions(url); using (WebApp.Start(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.
用浏览器打开
效果如下:`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(); }}
修改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(); } public static IAppBuilder UseDiDiDi(this IAppBuilder app) { return app.Use (); }}
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的管道概念其实简单易懂,在程序启动之前,向里面插入中间件,中间件决定请求是否继续向下走。在管道中的中间件可以拿到请求的所有信息以对请求进行处理,管道里的中间件执行结束之后,这个请求就被处理完成了,然后发回浏览器。
转载地址:http://uygzl.baihongyu.com/