微软.net系框架技术变迁要义

如果我们希望事情保持原状,就到了必须发生改变的时候了。
-----《豹》
.Net Framework
.Asp.Net Framework
Web Forms 模型
Asp.Net MVC 模型
.Web API Framework

极简web 服务的需求

Asp.Net Core

**

.Net Framework

**

.Asp.Net Framework

1999年秋,APS–>ASP.NET发布。
ASP.NET 框架包含IIS的一个扩展,能够捕捉HTTP请求,并通过ASP.NET的运行时环境处理他们。

在运行时环境中,通过找到能够处理该请求的组件,然后为浏览器准备一个HTTP响应包,来解析请求。运行时环境结构就想一个管道“:请求进入这个管道, 经历不同的阶段,知道被完整处理,之后其响应被写回到输出流中。

ASP.NET 提供了一个***有状态的、基于事件的编程模型***, 允许隐含的上下文从一个请求传递到另一个请求。这个设计理念收到传统桌面端开发的影响,这个设计也与同时期的竞争对手最大的区别。

1. Web Forms 模型
Web Forms 当初设计目标有两个:
一个是设计一个模型, 尽量是开发人员不用接触HTML,JS等前端脚本,Web Forms 模型 受到经典的客户机/服务器模型的影响,应用效果极好, 创造出了一个既包含免费服务器组件,又包含商用服务器组件的生态系统,直至2009年,得到MVC模式的补充。
第二个目标是尽量将ASP.NET和IIS 混合到一起。ASP.NET被设想为IIS的左膀右臂,而不只是一个插件,其运行时的环境将成为IIS结构的一部分。IIS7的集成管道工作模式下,IIS和ASP.NET共享相同的管道。请求进入IIS时候采取的路径与ASP.NET中采取的路径相同。ASP.NET只是负责处理请求,以及按照自己的需要拦截和预处理任何请求。

2. Asp.Net MVC 模型

Asp.Net MVC是一个全新的设计, 旨在更接近HTTP协议工作,没有尝试隐藏HTTP的任何功能,而是要求开发人员熟悉HTTP请求和响应的机制。

Asp.Net MVC团队尽力做到能够模拟整个HTTP上下文,却无法在框架中建立完整的、规范的依赖注入基础结构。

Asp.Net MVC是在新的跨领域需求的推动下(关注分离点、模块化、可测试),对编程模型进行重新设计的结果。

对于处理必须返回HTML内容的WEB请求,Asp.Net MVC编程模型是最灵活的、最容易理解的方式。但是,从某个时间开始,伴随着移动空间的爆发式发展,HTML不再是HTTP请求唯一可能的输出。就诞生了 WEB API。

.Web API Framework

移动设备出现后,能够请求WEB站点, 向任意类型的客户端提供任意类型的内容, 如JSON、XML、图片、PDF。任何能够发出HTTP请求的一段代码都是WEB站点的潜在客户端。而且, 某些解决方案的可变性变得至关重要。
在ASP.net 的空间中, 并没有多少余地来扩展基础机构,进而适应新的场景, 高度可扩展、云、平台无惯性。
Web Api 框架的出现旨在提供一个临时的解决方案, 对应瘦服务器的高需求,这种服务器能够提供RESTful接口,并与任意的HTTP客户端进行对话,而不做任何假定和限制。

极简web 服务的需求

近年来,软件行业出现了另外一个重要的变化,开始需要极简的WEB服务,也就是包围一段业务逻辑的一个薄薄的WEB服务层。
极简web服务器是一个HTTP端点,客户端可调用这个端点来获取基本的、主要基于文本的内容。这样的web服务器不需要运行复杂的、定制的管道,而是只需要接受HTTP请求,根据情况进行处理,然后返回一个HTTP响应。这个过程不应该有开销, 或者应该只有上下文的开销。
对客户端编程模型(如Angular)的运用进一步增加了对这种web服务的需求。

Asp.Net Core

2014年,ASP.NET团队设计了一个全新的ASP.NET,并按照OWIN 规范,设计了一个全新的运行时环境。
该团队主要目的是移除对旧的ASP.NET运行时—System.Web.dll的依赖。
该团队还有一个主要关键目标:是开发人员能够完全掌控管道,从而能够构建极简的WEB服务,又能够构建完整的网站。

减重和减负:.NET Core Framework
新的Asp.Net 的知道原则可归结为:

  • 使Asp.Net既能够完整访问现有的.NET Framework,又能访问其精简的版本, 这种版本去除了所有很少使用的、用途不大的依赖。
  • 使新的Asp.Net 环境与宿主服务器解耦。
    --------------.NET Core Framework
    去掉了平台依赖性,就能够修改新的、更加精简的.NET Framework,使其能够在其他操作系统上工作。

将Asp.Net 与宿主解耦
在这里插入图片描述
开放的WEB接口架构
在基于OWIN的架构中,宿主WEB服务器不在是IIS。
OWIN的英文全称是Open Web Interface for .NET。

如果仅从名称上解析,可以得出这样的信息:OWIN是针对.NET平台的开放Web接口。
那Web接口是谁和谁之间的接口呢?是Web应用程序与Web服务器之间的接口,OWIN就是.NET Web应用程序与Web服务器之间的接口。

为什么需要这样一个接口呢?因为.NET Web应用程序是运行于Web服务器之中的,.NET Web应用程序需要通过Web服务器接收用户的请求,并且通过Web服务器将响应内容发送用户。如果没有这样一个接口,.NET Web应用程序就要依赖于所运行的具体Web服务器,比如ASP.NET应用程序要依赖于IIS。有了这个接口,ASP.NET应用程序只需依赖这个抽象接口,不用关心所运行的Web服务器。

所以,OWIN的作用就是通过引入一组抽象接口,解耦了.NET Web应用程序与Web服务器,再次体现了接口的重要性。在软件开发中,每次解耦都是一次很大的进步。

被设计为跨平台的, 是开发人员能够创建运行在windows和Linux上的应用程序。ASP.NET CORE 包含一个内置的WEB服务器和一个运行应用程序的运行时环境。
这些系统模块被设计成极小的模块, 从而提供更多的机会来构建只要最小的开销就能运行的应用程序。
Asp.Net cORE 的整体架构
Asp.Net Core 的整体架构

注:
什么是 OWIN ?
  OWIN 的全称是 “Open Web Interface for .NET”, OWIN 在 .NET Web 服务器和 .NET Web 应用之间定义了一套标准的接口, 其目的是为了实现服务器与应用之间的解耦, 鼓励为 .NET Web 应用开发简单模块。

OWIN 是一个开源开放的标准, 有助于建设 .NET 开发的开源生态环境,OWIN 定义了如下几个概念:

服务器 (Server)

HTTP 服务器直接与客户端交互, 并用 OWIN 语义处理请求,服务器需要一个适配层将客户请求转换 成 OWIN 语义。 支持 OWIN 的服务器有 Katana 和 Nowin 。

Web 框架 (Web Framework)

构建在 OWIN 之上的自包含的独立组件, 向 Web 应用提供可用的对象模型或者接口。 Web 框架可 能需要一个适配层来转换 OWIN 语义。 支持 OWIN 的 Web 框架有:

Nancy
SignalR
WebApi
FubuMVC
Simple.Web
DuoVia.Http
Web 应用 (Web Application)

一个特定的 Web 应用, 通常构建在 Web 框架之上, 使用 OWIN 兼容的服务器运行。

中间件 (Middleware)

特定目的的服务器和应用之间的可插拔组件, 可以监视、 路由、 修改请求与响应。

宿主 (Host)

应用与服务器所在的进程, 主要负责应用的启动, 有些服务器自身也是宿主, 比如 Nowin 。

为什么使用 OWIN
  正如上面所说, OWIN 定义了 .NET Web 服务器与 .NET Web 应用之间的标准接口, 将应用与服务器 解耦, 使得便携式 .NET Web 应用以及跨平台的愿望成为现实, 标准的 OWIN 应用可以在任何 OWIN 兼容的服务器上运行, 不再依赖与 Windows 和 IIS 。
  历史渊源:过去,IIS作为.NET 开发者来说是最常用的Web Server(没有之一),源于微软产品的紧耦合关系,我们不得不将Website、Web Application、Web API等部署在IIS上,事实上在2010年前并没有什么不妥,但随着近些年来Web的发展,特别是移动互联网飞速发展,IIS作为Web Server已经暴露出他的不足了。主要体现在两个方面,ASP.NET (System.Web)紧耦合IIS,IIS紧耦合OS,这就意味着,我们的Web Framework必须部署在微软的操作系统上,难以跨平台。
  
ASP.NET 和 IIS
我们知道,不管是ASP.NET MVC 还是ASP.NET WEB API 等都是基于ASP.NET Framework的,这种关系从前缀就可以窥倪出来。而ASP.NET的核心正是System.Web这个程序集,而且System.Web紧耦合IIS,他存在于.NET Framework中。所以,这导致了Web Framework严重的局限性:

ASP.NET 的核心System.Web,而System.Web紧耦合IIS
System.Web 是.NET Framework重要组成,已有15年以上历史,沉重、冗余,性能差,难于测试,约2.5M
System.Web要更新和发布新功能必须等待.NET Framework发布
.但NET Framework是Windows的基础,往往不会随意更新。
所以要想获取最新的Web Framework是非常麻烦的,幸运的事,微软已经意识到了问题的严重性,最新的Web Framework都是通过Nuget来获取。

当然这是一部分原因,还有一层原因是ASP.NET & IIS实在太过于笨重,如何讲呢?

复杂的生命周期已成为累赘?简单来说,当请求到达服务器时,Windows内核组件HTTP.SYS组件捕获请求,他会分析请求并决定是否交给IIS来处理,当请求到达IIS之后,IIS会根据处理程序映射来匹配请求并交给对应的程序集(实现了ISAPI接口,比如我们熟知的aspnet_isapi.dll是专门用来处理ASP.NET Application)处理,最后加载了CLR运行环境,将请求交给aspnet_wp.exe去处理,这时复杂的ASP.NET生命周期往往令人头大,但事实上有很多时候我们并不需要他。
在这里插入图片描述

打开IIS,你会发现他提供了非常丰富的功能:缓存、身份验证、压缩、加密等。但随着移动互联网蓬勃的发展,特别是HTML 5越来越成熟的今天,我们看到越来越多的操作发生在客户端,而不是沉重的从服务器产生HTML返回,更多的是通过异步AJAX返回原生的数据。同理,对于 APP来说我们只需要Mobile Service返回数据。显然IIS显得笨重了点,而且IIS作为微软产品系的一环,耦合程度太高。所以我们迫切需要轻量、快速、可扩展的宿主来承载Web Application和Web Service。

IIS 和 OS
IIS必须是安装并运行在Windows操作系统中,这是微软产品的一贯风格,环环相套,但不得不考虑他们的限制和局限性:

IIS往往和操作系统(Windows Server)绑定在一起,这意味着对于一些新功能如WebSocket Protocol ,我们不得不等待操作系统Windows Sever 2012、Windows 8的发布(IIS 8.0)。
为了使用WebSocket这类新特性,他仅被IIS 8.0支持,如下所示:
在这里插入图片描述

这时你不得不去升级IIS,但升级操作系统可能会引发旧系统的不稳定性,所以要想平稳的升级IIS并不是简单的。

IIS作为经典的Web Server必须安装在Windows系统中,Windows Server需要授权使用。
正是由于微软产品系紧耦合的关系,才造成跨平台上的不足,这也是被饱受诟病。所以我们需要OWIN来解耦,在面向对象的世界里,接口往往是解耦的关键,如下图所示:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
OWIN的规范
现在我们已经了解了什么是OWIN已经为什么需要OWIN,现在是时候来分析一下OWIN的规范了。

OWIN Layers
实际上,OWIN的规范非常简单,他定义了一系列的层(Layer),并且他们的顺序是以堆(Stack)的形式定义,如下所示。OWIN中的接口被称之为应用程序委托或者AppFunc,用来在这些层之间通信。
在这里插入图片描述
OWIN定义了4层:

1. Host:

主要负责应用程序的配置和启动进程,包括初始化OWIN Pipeline、运行Server。

2. Server:

这是实际的Http Server,绑定套接字并监听的HTTP请求然后将Request和Response的Body、Header封装成符合OWIN规范的字典并发送到OWIN Middleware Pipeline中,最后Application为Response Data填充合适的字段输出。

3. Middleware:

称之为中间件、组件,位于Server与Application之间,用来处理发送到Pipeline中的请求,这类组件可以是简单的Logger或者是复杂的Web Framework比如Web API、SignalR,只要Sever连接成功,Middleware中间件可以是任何实现应用程序委托的组件。

4. Application:

这是具体的应用程序代码,可能在Web Framework之上。对于Web API、SignalR这类Web Framework中间件而言,我们仅仅是改变了他们的托管方式,而不是取代ASP.NET WEB API、SignalR原先的应用程序开发。所以该怎么开发就怎么开发,只不过我们将他们注册到OWIN Pipeline中去处理HTTP 请求,成为OWIN管道的一部分,所以此处的Application即正在意义上的处理程序代码。

Application Delegate
OWIN规范另一个重要的组成部分是接口的定义,用于Server和Middleware的交互。他并不是严格意义上的接口,而是一个委托并且每个OWIN中间件组件必须提供。
从字面上理解,每个OWIN中间件在必须有一个方法接受类型了IDictionary<string,object>的变量(俗称环境字典),然后必须返回Task来异步执行。

Environment Dictionary
环境字典包含了Request、Response所有信息以及Server State。通过Pipeline,每个中间件组件和层都可以添加额外的信息,但环境字典定义了一系列强制必须存在的Key,如下所示:

Request Data:
Response Data:
from :木宛城主
c#:使用Owin创建WebAPI
1.创建控制台项目
2.NuGet添加Microsoft.AspNet.WebApi.Owin和Microsoft.Aspnet.WebApi.OwinSelfHost
3.添加Startup类
1.1、Startup
Startup是OWIN约定的,用于对OWIN做相关配置,代码如下:

using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;

namespace OwinTest{
    public class Startup{
        public void Configuration(IAppBuilder appBuilder){
            //创建Web API 的配置
            var config = new HttpConfiguration();
            //启动标记路由
            config.MapHttpAttributeRoutes();
            config.Routes.MapHttpRoute(
                name:"DefaultApi",
                routeTemplate:"api/{controller}/{id}"
            );
            //将路有配置附加到appBuilder
            appBuilder.UseWebApi(config);
        }
    }
}

1.2、Controllers类
新建一个queryController类,代码如下:


```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;

namespace OwinTest{
    public class queryController:ApiController{
        //get api
        public string Get(string id)
        {
            return id;
        }
        // POST api
         public string Post([FromBody] string value)
        {
            return value;
        }
        // PUT api
        public void Put(int id, string value)
        {
        }
        // DELETE api
        public void Delete(int id)
        {
        }
    }
}
自建一个PersonController类,代码如下:

```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Http;

namespance OwinTest{
    public class PersonController:ApiController{
        Person[] personList = new Person[] {
            new Person { Id= 1,Age = 2,Name="DANNY"},
            new Person { Id = 2,Age = 3,Name = "Danny123"},
            new Person { Id =3,Age = 4,Name = "dANNY456"}
        };
        
        [HttpGet]
        [Route("api/person/getAll")]
        public List<Person> GetListAll(){
            return personList.toList();
        }
        
        public List<Person> Get(string id){
            return personList.toList();
        }
    }
}

1.3、启动WebAPI服务
Program代码如下,启动项目:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Http;

class Program
    {
        static void Main(string[] args)
        {
            string baseAddress = "http://localhost:9000/";
            using (Microsoft.Owin.Hosting.WebApp.Start<Startup>(url: baseAddress))
            {
                HttpClient client = new HttpClient();
                Console.WriteLine(baseAddress);
                Console.ReadLine();
            }
        }
    }

二、PostMan接口测试
2.1、自定义Route
调用PersonController的GetListAll方法
Get http://localhost:9000/api/person/getAll

调用PersonController的Get方法(其中ok只是参数)
Get http://localhost:9000/api/Person/ok

调用queryController的Get方法
Get http://localhost:9000/api/query/abc

调用queryController的Post方法
Post http://localhost:9000/api/query
以下分别是string和Pserson的参数传入:

string

stringdemo

Person

{
    "Id":1,
    "Name":"Danny",
    "Age":18
}

public class Person{
    public int Id{set;get;}
    public string Name{get;set;}
    public int Aget{set;get;}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是刘彦宏吖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值