ASP.NET Web API 管道模型

简介:

ASP.NET Web API 管道模型

前言

ASP.NET Web API是一个独立的框架,也有着自己的一套消息处理管道,不管是在WebHost宿主环境还是在SelfHost宿主环境请求和响应都是从消息管道经过的,这是必经之地,本篇就为大家简单的介绍一下ASP.NET Web API框架中的管道对象模型。

 

 

ASP.NET Web API路由、管道

l  ASP.NET Web API 开篇介绍示例

l  ASP.NET Web API 路由对象介绍

l  ASP.NET Web API 管道模型

l  ASP.NET Web API selfhost宿主环境中管道、路由

l  ASP.NET Web API webhost宿主环境中管道、路由

 

管道模型介绍

HttpMessageHandler消息处理程序(基类)

1
2
3
4
5
6
7
    publicabstractclassHttpMessageHandler : IDisposable
    {
         protectedHttpMessageHandler();
         publicvoidDispose();
         protectedvirtualvoidDispose(booldisposing);
         protectedinternalabstractTask<HttpResponseMessage>SendAsync(HttpRequestMessagerequest, CancellationTokencancellationToken);
}


上面的代码中定义的是消息处理程序基类,在管道中的每一个消息处理部分都是继承自它。

并且定义了一个会执行异步操作的SendAsync()方法,这个方法也是串联管道中各个消息处理程序的一个入口,但是并不是靠它来串联。

 

DelegatingHandler消息处理程序(基类)

1
2
3
4
5
6
7
8
9
    publicabstractclassDelegatingHandler : HttpMessageHandler
    {
         protectedDelegatingHandler();
         protectedDelegatingHandler(HttpMessageHandlerinnerHandler);
         publicHttpMessageHandlerInnerHandler {  get set ; }
  
         protectedoverridevoidDispose(booldisposing);
         protectedinternaloverrideTask<HttpResponseMessage>SendAsync(HttpRequestMessagerequest, CancellationTokencancellationToken);
}


这里的DelegatingHandler继承自HttpMessageHandler类型,而且DelegatingHandler也是抽象类型,DelegatingHandler类型并不是就是简单的继承,而是对基类进行了扩展,使之变成一个带指向箭头(对象引用)的对象类型也就是InnerHandler属性,InnerHandler属性的值就是在当前这个消息处理程序的下一个消息处理程序,DelegatingHandler类型对基类的扩展,HttpMessageHandler类型我感觉它的存在就是一个规范,从管道中的第一个处理程序开始一直到最后一个,除了最后一个消息处理程序,其他的都是DelegatingHandler类型的子类(当然也是HttpMessageHandler的子类),最后一个消息处理程序是直接继承自HttpMessageHandler类型,因为它是最后一个处理程序了不必要有指向下一个处理程序的属性,这种对职责的划分真的很优美,说不出好在哪就是觉得漂亮。

 

HttpServer消息处理程序(实现类-管道头)

1
2
3
4
5
6
7
8
9
10
11
12
13
publicclassHttpServer : DelegatingHandler
    {
         publicHttpServer();
         publicHttpServer(HttpConfigurationconfiguration);
         publicHttpServer(HttpMessageHandlerdispatcher);
         publicHttpServer(HttpConfigurationconfiguration, HttpMessageHandlerdispatcher);
         publicHttpConfigurationConfiguration {  get ; }
         publicHttpMessageHandlerDispatcher {  get ; }
  
         protectedoverridevoidDispose(booldisposing);
         protectedvirtualvoidInitialize();
         protectedoverrideTask<HttpResponseMessage>SendAsync(HttpRequestMessagerequest, CancellationTokencancellationToken);
}


HttpServer类型继承自DelegatingHandler类型,是作为管道中第一个消息处理的,要说明的是重载的这些构造函数,如果只是采用默认的构造函数的话,HttpConfiguration类型的参数默认的就是实例化HttpConfiguration类型,而HttpMEssageHandler类型的参数默认的是实例化HttpRoutingDispatcher类型的消息处理器,并且是赋值到Dispatcher属性的,是作为管道中最后一个消息处理器的(真正的操作实际不是它,后面篇幅会有讲到)。

 

HttpRoutingDispatcher消息处理程序(实现类-管道尾)

1
2
3
4
5
6
7
8
9
10
11
12
    publicclassHttpRoutingDispatcher : HttpMessageHandler
    {
         //Fields
         privatereadonlyHttpConfiguration_configuration;
         privatereadonlyHttpMessageInvoker_defaultInvoker;
  
         //Methods
         publicHttpRoutingDispatcher(HttpConfigurationconfiguration);
         publicHttpRoutingDispatcher(HttpConfigurationconfiguration, HttpMessageHandlerdefaultHandler);
         privatestaticvoidRemoveOptionalRoutingParameters(IDictionary< string object >routeValueDictionary);
         protectedoverrideTask<HttpResponseMessage>SendAsync(HttpRequestMessagerequest, CancellationTokencancellationToken);
}


HttpRoutingDispatcher类型继承自HttpMessageHandler类型,上面也说到过它是作为在管道中最后一个消息处理器的,说是可以这么说,但是真正执行的却不是它,而是在执行重载的构造函数的时候会默认的生成HttpControllerDispatcher类型作为HttpMessageHandler类型的构造函数参数,这里就不对它进行过多的阐述了,后面的篇幅自然会说明的很详细。

下面我们来看一下ASP.NET Web API管道的大概示意图。

1

wKiom1PgKSfT4RsYAAHCZPgZAb0108.jpg

(蓝色线条表示请求,红色线条表示响应)

这样的示意图说明的不是太清晰下面我们用《ASP.NET Web API 开篇介绍示例》中的SelfHost环境下的示例来演示一下,这样大家自然就会清楚这个流程了。

 

首先我们定义一个消息处理器类型命令为CustomDelegatingHandler,并且继承自DelegatingHandler类型。示例代码如下

代码1-1

1
2
3
4
5
6
7
8
9
10
11
12
13
    publicclassCustomDelegatingHandler : DelegatingHandler
    {
         protectedoverrideTask<HttpResponseMessage>SendAsync(HttpRequestMessagerequest, System.Threading.CancellationTokencancellationToken)
         {
             Console.WriteLine(request.RequestUri.OriginalString+ "____" +request.Method.Method);
  
             Task<HttpResponseMessage>responseMessage= base .SendAsync(request, cancellationToken);
  
             Console.WriteLine(responseMessage.Result.RequestMessage.Method.Method);
  
             returnresponseMessage;
         }
}


 

随之我们在SelfHost环境下的服务端在注册路由之后注册刚才我们新建的消息处理程序对象,示例代码如下:

代码1-2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
staticvoidMain( string [] args)
         {
             HttpSelfHostConfigurationselfHostConfiguration=
                 newHttpSelfHostConfiguration( "http://localhost/selfhost" );
             using  (HttpSelfHostServerselfHostServer=newHttpSelfHostServer(selfHostConfiguration))
             {
                 selfHostServer.Configuration.Routes.MapHttpRoute(
                     "DefaultApi" "api/{controller}/{id}" new  { id=RouteParameter.Optional });
                 RegistrationMessageHandler(selfHostServer.Configuration);
  
                 selfHostServer.OpenAsync();
  
                 Console.WriteLine( "服务器端服务监听已开启" );
                 Console.Read();
             }
  
         }
         staticvoidRegistrationMessageHandler(HttpConfigurationhttpconfiguration)
         {
             httpconfiguration.MessageHandlers.Add(newHttpMessageHandlers.CustomDelegatingHandler());
         }


 

在注册完毕,并且服务器已经启动开启请求监听,客户端也随之发出请求之后,我们再来看一下客户端发出的请求以及类型,如下图。

2

wKioL1PgKmfShi5LAAOgbQwgN90619.jpg

 

这个时候我们再来看一下服务端管道处理情况,如下图。

3

wKiom1PgKVuSY0HmAAJFEVKTkr0744.jpg

每一个红框圈中的部分都表示着一个请求和响应的流程跟图2中的所有请求是对应的,可以从代码1-1中就可以看出输出的内容。

如果说这样的示例并不不明显,不能让人很清楚明白的了解管道的执行过程以及顺序,那我们定义两个处理程序,并且修改代码1-1,示例代码如下:

代码1-3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    publicclassCustomDelegatingHandler : DelegatingHandler
    {
         protectedoverrideTask<HttpResponseMessage>SendAsync(HttpRequestMessagerequest, System.Threading.CancellationTokencancellationToken)
         {
             Console.WriteLine( this .GetType().Name+ ":" +request.RequestUri.OriginalString+ "____" +request.Method.Method);
  
             Task<HttpResponseMessage>responseMessage= base .SendAsync(request, cancellationToken);
  
             Console.WriteLine( this .GetType().Name+ ":" +responseMessage.Result.RequestMessage.Method.Method);
  
             returnresponseMessage;
         }
    }
  
    publicclassCustomDelegatingHandler_1 : DelegatingHandler
    {
         protectedoverrideTask<HttpResponseMessage>SendAsync(HttpRequestMessagerequest, System.Threading.CancellationTokencancellationToken)
         {
             Console.WriteLine( this .GetType().Name+ ":" +request.RequestUri.OriginalString+ "____" +request.Method.Method);
  
             Task<HttpResponseMessage>responseMessage= base .SendAsync(request, cancellationToken);
  
             Console.WriteLine( this .GetType().Name+ ":" +responseMessage.Result.RequestMessage.Method.Method);
  
             returnresponseMessage;
         }
}


 

随之我们注册管理处理程序的地方也要新增一个消息处理程序,示例代码如下:

代码1-4

1
2
3
4
5
         staticvoidRegistrationMessageHandler(HttpConfigurationhttpconfiguration)
         {
             httpconfiguration.MessageHandlers.Add(newHttpMessageHandlers.CustomDelegatingHandler());
             httpconfiguration.MessageHandlers.Add(newHttpMessageHandlers.CustomDelegatingHandler_1());
         }


 

这个时候按照图2之前的那段说明操作,再看一下服务端的管道处理情况,请求还是那些个请求,看下示意图如下:

4

wKioL1PgKpSjE3ptAARBy2XFCd0591.jpg

(红框部分的代表就是跟上面所说的一样,一个请求一个响应管道所对应的处理情况)

最后再看一下图5结合图4,这样更好更容易理解。

5

wKiom1PgKYmQ05LqAAHeTWgc08Q737.jpg







     本文转自jinyuan0829 51CTO博客,原文链接:http://blog.51cto.com/jinyuan/1535778,如需转载请自行联系原作者




相关文章
|
19天前
|
开发框架 前端开发 JavaScript
ASP.NET Web Pages - 教程
ASP.NET Web Pages 是一种用于创建动态网页的开发模式,采用HTML、CSS、JavaScript 和服务器脚本。本教程聚焦于Web Pages,介绍如何使用Razor语法结合服务器端代码与前端技术,以及利用WebMatrix工具进行开发。适合初学者入门ASP.NET。
|
2月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
58 4
|
2月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
159 3
|
10天前
|
Kubernetes 安全 Devops
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
36 10
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
|
22天前
|
开发框架 .NET 程序员
驾驭Autofac,ASP.NET WebApi实现依赖注入详细步骤总结
Autofac 是一个轻量级的依赖注入框架,专门为 .NET 应用程序量身定做,它就像是你代码中的 "魔法师",用它来管理对象的生命周期,让你的代码更加模块化、易于测试和维护
驾驭Autofac,ASP.NET WebApi实现依赖注入详细步骤总结
|
19天前
|
开发框架 .NET PHP
ASP.NET Web Pages - 添加 Razor 代码
ASP.NET Web Pages 使用 Razor 标记添加服务器端代码,支持 C# 和 Visual Basic。Razor 语法简洁易学,类似于 ASP 和 PHP。例如,在网页中加入 `@DateTime.Now` 可以实时显示当前时间。
|
1月前
|
前端开发 API 开发者
Python Web开发者必看!AJAX、Fetch API实战技巧,让前后端交互如丝般顺滑!
在Web开发中,前后端的高效交互是提升用户体验的关键。本文通过一个基于Flask框架的博客系统实战案例,详细介绍了如何使用AJAX和Fetch API实现不刷新页面查看评论的功能。从后端路由设置到前端请求处理,全面展示了这两种技术的应用技巧,帮助Python Web开发者提升项目质量和开发效率。
52 1
|
1月前
|
JSON API 数据格式
如何使用Python和Flask构建一个简单的RESTful API。Flask是一个轻量级的Web框架
本文介绍了如何使用Python和Flask构建一个简单的RESTful API。Flask是一个轻量级的Web框架,适合小型项目和微服务。文章从环境准备、创建基本Flask应用、定义资源和路由、请求和响应处理、错误处理等方面进行了详细说明,并提供了示例代码。通过这些步骤,读者可以快速上手构建自己的RESTful API。
63 2
|
2月前
|
监控 负载均衡 API
Web、RESTful API 在微服务中有哪些作用?
在微服务架构中,Web 和 RESTful API 扮演着至关重要的角色。它们帮助实现服务之间的通信、数据交换和系统的可扩展性。
54 2
|
2月前
|
开发框架 .NET API
Windows Forms应用程序中集成一个ASP.NET API服务
Windows Forms应用程序中集成一个ASP.NET API服务
106 9
下一篇
DataWorks