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,如需转载请自行联系原作者




相关文章
|
20天前
|
自然语言处理 安全 API
API First:模型驱动的阿里云API保障体系
本文介绍了阿里云在API设计和管理方面的最佳实践。首先,通过API First和模型驱动的方式确保API的安全、稳定和效率。其次,分享了阿里云内部如何使用CloudSpec IDL语言及配套工具保障API质量,并实现自动化生成多语言SDK等工具。接着,描述了API从设计到上线的完整生命周期,包括规范校验、企业级能力接入、测试和发布等环节。最后,展望了未来,强调了持续提升API质量和开源CloudSpec IDL的重要性,以促进社区共建更好的API生态。
|
16天前
|
人工智能 前端开发 API
Gemini Coder:基于 Google Gemini API 的开源 Web 应用生成工具,支持实时编辑和预览
Gemini Coder 是一款基于 Google Gemini API 的 AI 应用生成工具,支持通过文本描述快速生成代码,并提供实时代码编辑和预览功能,简化开发流程。
102 38
Gemini Coder:基于 Google Gemini API 的开源 Web 应用生成工具,支持实时编辑和预览
|
12天前
|
机器学习/深度学习 人工智能 安全
GLM-Zero:智谱AI推出与 OpenAI-o1-Preview 旗鼓相当的深度推理模型,开放在线免费使用和API调用
GLM-Zero 是智谱AI推出的深度推理模型,专注于提升数理逻辑、代码编写和复杂问题解决能力,支持多模态输入与完整推理过程输出。
142 24
GLM-Zero:智谱AI推出与 OpenAI-o1-Preview 旗鼓相当的深度推理模型,开放在线免费使用和API调用
|
3月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
66 4
|
3月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
217 3
|
9天前
|
开发框架 数据可视化 .NET
.NET 中管理 Web API 文档的两种方式
.NET 中管理 Web API 文档的两种方式
31 14
|
1月前
|
存储 人工智能 API
AgentScope:阿里开源多智能体低代码开发平台,支持一键导出源码、多种模型API和本地模型部署
AgentScope是阿里巴巴集团开源的多智能体开发平台,旨在帮助开发者轻松构建和部署多智能体应用。该平台提供分布式支持,内置多种模型API和本地模型部署选项,支持多模态数据处理。
253 4
AgentScope:阿里开源多智能体低代码开发平台,支持一键导出源码、多种模型API和本地模型部署
|
1月前
|
Kubernetes 安全 Devops
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
74 10
有效抵御网络应用及API威胁,聊聊F5 BIG-IP Next Web应用防火墙
|
2月前
|
开发框架 .NET 程序员
驾驭Autofac,ASP.NET WebApi实现依赖注入详细步骤总结
Autofac 是一个轻量级的依赖注入框架,专门为 .NET 应用程序量身定做,它就像是你代码中的 "魔法师",用它来管理对象的生命周期,让你的代码更加模块化、易于测试和维护
驾驭Autofac,ASP.NET WebApi实现依赖注入详细步骤总结
|
2月前
|
人工智能 Java API
ChatClient:探索与AI模型通信的Fluent API
【11月更文挑战第22天】随着人工智能(AI)技术的飞速发展,越来越多的应用场景开始融入AI技术以提升用户体验和系统效率。在Java开发中,与AI模型通信成为了一个重要而常见的需求。为了满足这一需求,Spring AI引入了ChatClient,一个提供流畅API(Fluent API)的客户端,用于与各种AI模型进行通信。本文将深入探讨ChatClient的底层原理、业务场景、概念、功能点,并通过Java代码示例展示如何使用Fluent API与AI模型进行通信。
66 8