HTML5技术

细说ASP.NET Core与OWIN的关系 - 偏僻的维度

字号+ 作者:H5之家 来源:博客园 2016-06-04 13:00 我要评论( )

前言 最近这段时间除了工作,所有的时间都是在移植我以前实现的一个Owin框架,相当移植到到Core的话肯定会有很多坑,这个大家都懂,以后几篇文章可能会围绕这个说下,暂时就叫《Dotnet Core踩坑记》吧,呵呵。 Owin ASP.NET vNext刚推出的时候,号称是Owin的

  前言

  最近这段时间除了工作,所有的时间都是在移植我以前实现的一个Owin框架,相当移植到到Core的话肯定会有很多坑,这个大家都懂,以后几篇文章可能会围绕这个说下,暂时就叫《Dotnet Core踩坑记》吧,呵呵。

  Owin

  ASP.NET vNext刚推出的时候,号称是Owin的一个实现,在  上,直到现在还保留着这样一段描述。

  Implementations

  很多开发者纷纷实现着自己的Owin框架,也写很多应用到了实际的生产环境中,当然我也是其中一员。

  ASP.NET Core

  移植过程中,会发现有很多的不同,还有遇到新的API不知道怎么使用,这时候看文档还不如直接看源码来的痛快。

  在看完AspCore.Mvc后才发现,一点关于Owin的内容都没有;但很明显官方文档上说是支持Owin协议的,后来我硬着头皮去看了看KestrelHttpServer和HttpAbstractions两个项目,后来才发现原来真的没有一点点的Owin协议内容啊(一定要给MS差评)。

  好吧,只能看看MS是怎么支持Owin的,在HttpAbstractions项目里发现了Microsoft.AspNetCore.Owin这样一个子项目,看完只是想说:“你这意思这叫向下兼容?” ,算了。 现在只要在Asp.net core项目里加入依赖Microsoft.AspNet.Owin就可以IApplicationBuilder接口的扩展方法UseOwin进行Owin中间件的调用。如下:

  添加依赖:

"dependencies": { "Microsoft.AspNet.Server.Kestrel": "1.0.0-*", "Microsoft.AspNet.Owin": "1.0.0-*" },

  在Startup中加入UseOwin:

 

Configure(IApplicationBuilder app) 2 { 3 app.UseOwin(pipeline => 4 { 5 pipeline(next => OwinHello); 6 }); 7 }

 

  当然OwinHello的内容一定是一个标准Owin中间件的内容了:

1 public Task OwinHello(IDictionary<string, object> environment) 2 { ; 4 byte[] responseBytes = Encoding.UTF8.GetBytes(responseText); ]; ]; ] = new string[] { responseBytes.Length.ToString(CultureInfo.InvariantCulture) }; ] = }; 9 return responseStream.WriteAsync(responseBytes, 0, responseBytes.Length); 10 }

  Kestrel

  既然新的服务器已经不在支持Owin协议了,那个是怎么通信的?

  这个问题在ASP.NET Core管道深度剖析系列文章中被提到过一些,其实每一个HttpContext在被创建出来都会依赖一个IFeatureCollection集合。

  IFeatureCollection这个接口用于描述某个对象所具有的一组特征,由一组Feature接口组成。

  列出其中一个IHttpConnectionFeature接口,用于获得Http的连接信息:

public class HttpConnectionFeature : IHttpConnectionFeature { public string ConnectionId { get; set; } public IPAddress LocalIpAddress { get; set; } public int LocalPort { get; set; } public IPAddress RemoteIpAddress { get; set; } public int RemotePort { get; set; } }

  阅读kestrel源码,发现每一次接受tcp连接,都会将Http流,封装在一个帧Frame,它被描述成一个单向或双向的request和response。 并组装成特征集合供上层应用进行使用。

  最后

  最后就发一段Owin字典对应Feature的源码吧:

_entries = new Dictionary<string, FeatureMap>() { { OwinConstants.RequestProtocol, new FeatureMap<IHttpRequestFeature>(feature => feature.Protocol, () => string.Empty, (feature, value) => feature.Protocol = Convert.ToString(value)) }, { OwinConstants.RequestScheme, new FeatureMap<IHttpRequestFeature>(feature => feature.Scheme, () => string.Empty, (feature, value) => feature.Scheme = Convert.ToString(value)) }, { OwinConstants.RequestMethod, new FeatureMap<IHttpRequestFeature>(feature => feature.Method, () => string.Empty, (feature, value) => feature.Method = Convert.ToString(value)) }, { OwinConstants.RequestPathBase, new FeatureMap<IHttpRequestFeature>(feature => feature.PathBase, () => string.Empty, (feature, value) => feature.PathBase = Convert.ToString(value)) }, { OwinConstants.RequestPath, new FeatureMap<IHttpRequestFeature>(feature => feature.Path, () => string.Empty, (feature, value) => feature.Path = Convert.ToString(value)) }, { OwinConstants.RequestQueryString, new FeatureMap<IHttpRequestFeature>(feature => Utilities.RemoveQuestionMark(feature.QueryString), () => string.Empty, (feature, value) => feature.QueryString = Utilities.AddQuestionMark(Convert.ToString(value))) }, { OwinConstants.RequestHeaders, new FeatureMap<IHttpRequestFeature>(feature => Utilities.MakeDictionaryStringArray(feature.Headers), (feature, value) => feature.Headers = Utilities.MakeHeaderDictionary((IDictionary<string, string[]>)value)) }, { OwinConstants.RequestBody, new FeatureMap<IHttpRequestFeature>(feature => feature.Body, () => Stream.Null, (feature, value) => feature.Body = (Stream)value) }, { OwinConstants.RequestUser, new FeatureMap<IHttpAuthenticationFeature>(feature => feature.User, () => null, (feature, value) => feature.User = (ClaimsPrincipal)value) }, { OwinConstants.ResponseStatusCode, new FeatureMap<IHttpResponseFeature>(feature => feature.StatusCode, () => 200, (feature, value) => feature.StatusCode = Convert.ToInt32(value)) }, { OwinConstants.ResponseReasonPhrase, new FeatureMap<IHttpResponseFeature>(feature => feature.ReasonPhrase, (feature, value) => feature.ReasonPhrase = Convert.ToString(value)) }, { OwinConstants.ResponseHeaders, new FeatureMap<IHttpResponseFeature>(feature => Utilities.MakeDictionaryStringArray(feature.Headers), (feature, value) => feature.Headers = Utilities.MakeHeaderDictionary((IDictionary<string, string[]>)value)) }, { OwinConstants.ResponseBody, new FeatureMap<IHttpResponseFeature>(feature => feature.Body, () => Stream.Null, (feature, value) => feature.Body = (Stream)value) },

  只能说还好,性能并没有太多的损耗,粘的不全,全的自己看吧 : ) 

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • Dora.Interception: 一个为.NET Core度身定制的AOP框架 - Artech

    Dora.Interception: 一个为.NET Core度身定制的AOP框架 - Artech

    2017-05-02 11:00

  • 如何在 ASP.NET Core 中发送邮件 - Savorboard

    如何在 ASP.NET Core 中发送邮件 - Savorboard

    2017-05-02 08:02

  • 十二个 ASP.NET Core 例子 - Savorboard

    十二个 ASP.NET Core 例子 - Savorboard

    2017-04-27 16:01

  • ASP.NET MVC5请求管道和生命周期 - 雪飞鸿

    ASP.NET MVC5请求管道和生命周期 - 雪飞鸿

    2017-04-24 08:04

网友点评