前言

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

  接下来我对我在移植过程中发现的一些问题进行了总结,今天主要说说Owin。说到Owin就不能不提Katana项目和宇内大神的Tinyfox了,当然关于这两块内容这篇文章就不多涉及了,博友可以自己在博客园内搜索关于Owin的文章还是挺多的。

  Owin

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

  Implementations

  •     Katana
  •     Freya
  •     ASP.NET vNext

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

  ASP.NET Core

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

  在看完AspCore.Mvc后才发现,一点关于Owin的内容都没有;但很明显官方文档上说是支持Owin协议的,后来我硬着头皮去看了看KestrelHttpServerHttpAbstractions两个项目,后来才发现原来真的没有一点点的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:

 public void Configure(IApplicationBuilder app)
{
app.UseOwin(pipeline =>
{
pipeline(next => OwinHello);
});
}

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

 public Task OwinHello(IDictionary<string, object> environment)
{
string responseText = "Hello World via OWIN";
byte[] responseBytes = Encoding.UTF8.GetBytes(responseText);
var responseStream = (Stream)environment["owin.ResponseBody"];
var responseHeaders = (IDictionary<string, string[]>)environment["owin.ResponseHeaders"];
responseHeaders["Content-Length"] = new string[] { responseBytes.Length.ToString(CultureInfo.InvariantCulture) };
responseHeaders["Content-Type"] = new string[] { "text/plain" };
return responseStream.WriteAsync(responseBytes, , responseBytes.Length);
}

  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, () => , (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) },

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

  当然MS这样做也是有用意义的,他们不太喜欢字典的方式,于是用Feature这种方式将这些内容,"强类型化了"。这对于底层的Server来说,很快能基于这组特征二次开发出一套中间件来支持ASP.NET Core,当然直接在Server内实现这样性能也会更高。

  只能说API变化有点快吧,但是对于开源,看几天源码就全明白了,这对于我们dotnet开发者来说,真是大大的好事儿。

  

细说ASP.NET Core与OWIN的关系的更多相关文章

  1. 细说ASP.NET Core静态文件的缓存方式

    一.前言 我们在优化Web服务的时候,对于静态的资源文件,通常都是通过客户端缓存.服务器缓存.CDN缓存,这三种方式来缓解客户端对于Web服务器的连接请求压力的. 本文指在这三个方面,在ASP.NET ...

  2. ASP.NET Core 中文文档 第三章 原理(16).NET开放Web接口(OWIN)

    原文:Open Web Interface for .NET (OWIN) 作者:Steve Smith. Rick Anderson 翻译:谢炀(kiler398) 校对:孟帅洋(书缘) ASP.N ...

  3. 使用依赖关系注入在 ASP.NET Core 中编写干净代码

    ASP.NET Core 1.0 是 ASP.NET 的完全重新编写,这个新框架的主要目标之一就是更多的模块化设计.即,应用应该能够仅利用其所需的框架部分,方法是框架在它们请求时提供依赖关系.此外,使 ...

  4. [转]使用依赖关系注入在 ASP.NET Core 中编写干净代码

    本文转自:http://blog.jobbole.com/101270/ 原文出处: Steve Smith    ASP.NET Core 1.0 是 ASP.NET 的完全重新编写,这个新框架的主 ...

  5. ASP.NET Core 运行原理解剖[4]:进入HttpContext的世界

    HttpContext是ASP.NET中的核心对象,每一个请求都会创建一个对应的HttpContext对象,我们的应用程序便是通过HttpContext对象来获取请求信息,最终生成响应,写回到Http ...

  6. ASP.NET Core 认证与授权[4]:JwtBearer认证

    在现代Web应用程序中,通常会使用Web, WebApp, NativeApp等多种呈现方式,而后端也由以前的Razor渲染HTML,转变为Stateless的RESTFulAPI,因此,我们需要一种 ...

  7. 你真的了解ASP.NET Core 部署模型吗?

    ----------------------------   以下内容针对 ASP.NET Core2.1,2.2出现IIS进程内寄宿 暂不展开讨论-------------------------- ...

  8. 在IIS上发布并运行ASP.NET Core

    英文原文地址:https://weblog.west-wind.com/posts/2016/Jun/06/Publishing-and-Running-ASPNET-Core-Application ...

  9. 【分享】Asp.net Core相关教程及开源项目

    入门 全新的ASP.NET:  https://www.cnblogs.com/Leo_wl/p/5654828.html 在IIS上部署你的ASP.NET Core项目: https://www.c ...

随机推荐

  1. Android 自定义View 总结

    Android系统本身给我们提供十分丰硕的组件让我们实现包罗万象的UI效果,与此同时,我们也能够非常方便实现各种方法来实现各种强大的功能.通过继承现有的UI控件,我们也能够拓展现有的功能.我们也能够完 ...

  2. 你以为的ASP.NET文件上传大小限制是你以为的吗

    我们以为的文件大小限制 我们大家都知道ASP.NET为我们提供了文件上传服务器控件FileUpload,默认情况下可上传的最大文件为4M,如果要改变可上传文件大小限制,那么我们可以在web.confi ...

  3. dojo的发展历史

    dojo的开始要从2004年初开始说起,那时dojo之父 Alex Russell 在Informatica公司内从事一个名为netWindows的项目,这个项目的目的是在浏览器环境下提供创建窗口化界 ...

  4. 项目八:团队项目——Alpha阶段项目总结

    1.项目的预期目标 a.完成游戏的基本功能 b.游戏难度的玩家手动调节 c.游戏能够良好的运行完成 与前期的需求分析对比: 第一点不同是游戏的难度调节,原来是想通过选择难度来调节的,但由于难度的分层上 ...

  5. 用“MEAN”技术栈开发web应用(一)AngularJs前端架构

    前言 不知何时突然冒出“MEAN技术栈”这个新词,听起来很牛逼的样子,其实就是我们已经熟悉了的近两年在前端比较流行的技术,mongodb.express.angularjs.nodejs,由于这几项技 ...

  6. IOS UIView 02- 深入理解 Scroll Views

    注:本人是翻译过来,并且加上本人的一点见解. 前言 可能你很难相信 UIScrollView 和一个标准的 UIView 差异并不大,scroll view 确实会多出一些方法,但这些方法只是和 UI ...

  7. Redis总结笔记(一):安装和常用命令

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/112.html?1455860824 一.redis简单介绍 redis是 ...

  8. 06- Shell脚本学习--其它

    Shell输入输出重定向 Unix 命令默认从标准输入设备(stdin)获取输入,将结果输出到标准输出设备(stdout)显示.一般情况下,标准输入设备就是键盘,标准输出设备就是终端,即显示器. 输出 ...

  9. 数据库MySQL开篇

    作为一名前端,后天方面的知识虽说不一定要精通后台但是对后台方面的知识有一定了解是非常必要的. 今天先说一些概念方面的,因本人才疏学浅,对于数据库这方面的自学相当于摸着石头过河,有什么写的不对的地方,希 ...

  10. lua实现深度拷贝table表

    lua当变量作为函数的参数进行传递时,类似的也是boolean,string,number类型的变量进行值传递.而table,function,userdata类型的变量进行引用传递.故而当table ...