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




相关文章
|
JSON 监控 网络协议
干货分享“对接的 API 总是不稳定,网络分层模型” 看电商 API 故障的本质
本文从 OSI 七层网络模型出发,深入剖析电商 API 不稳定的根本原因,涵盖物理层到应用层的典型故障与解决方案,结合阿里、京东等大厂架构,详解如何构建高稳定性的电商 API 通信体系。
|
自然语言处理 安全 API
API First:模型驱动的阿里云API保障体系
本文介绍了阿里云在API设计和管理方面的最佳实践。首先,通过API First和模型驱动的方式确保API的安全、稳定和效率。其次,分享了阿里云内部如何使用CloudSpec IDL语言及配套工具保障API质量,并实现自动化生成多语言SDK等工具。接着,描述了API从设计到上线的完整生命周期,包括规范校验、企业级能力接入、测试和发布等环节。最后,展望了未来,强调了持续提升API质量和开源CloudSpec IDL的重要性,以促进社区共建更好的API生态。
|
11月前
|
JSON API 调度
Midjourney 技术拆解与阿里云开发者实战指南:从扩散模型到 API 批量生成
Midjourney深度解析:基于优化Stable Diffusion,实现文本到图像高效生成。涵盖技术架构、扩散模型原理、API调用、批量生成系统及阿里云生态协同,助力开发者快速落地AIGC图像创作。
1274 0
|
11月前
|
人工智能 API 监控
告别多接口拼凑!阿里云 API 模型聚合实现技术能力协同跃迁
API聚合整合400+国内外AI模型,统一接口、屏蔽差异,降低开发与维护成本,提升效率与系统稳定性,助力开发者高效应对多API调用困境。
1158 0
|
存储 人工智能 API
AgentScope:阿里开源多智能体低代码开发平台,支持一键导出源码、多种模型API和本地模型部署
AgentScope是阿里巴巴集团开源的多智能体开发平台,旨在帮助开发者轻松构建和部署多智能体应用。该平台提供分布式支持,内置多种模型API和本地模型部署选项,支持多模态数据处理。
15919 78
AgentScope:阿里开源多智能体低代码开发平台,支持一键导出源码、多种模型API和本地模型部署
|
11月前
|
人工智能 前端开发 测试技术
Kimi K2 模型更新,带来更强的代码能力、更快的 API
今天,Kimi K2 模型的最新版本 0905 开源发布,进一步提升其在真实编程任务中的表现
1962 0
本地用阿里云API调用的r1模型,返回的think字段中有奇怪的东西,并且停止思考
这两张图片展示了模型生成内容时可能出现的异常情况,包括图像模糊、结构错误或不符合预期的结果。这可能是由于模型训练数据不足、输入指令不清晰或模型本身存在局限性所致。建议优化输入提示词或调整模型参数以提升输出质量。
|
中间件 Go
Golang | Gin:net/http与Gin启动web服务的简单比较
总的来说,`net/http`和 `Gin`都是优秀的库,它们各有优缺点。你应该根据你的需求和经验来选择最适合你的工具。希望这个比较可以帮助你做出决策。
725 35
|
人工智能 算法 安全
OpenRouter 推出百万 token 上下文 AI 模型!Quasar Alpha:提供完全免费的 API 服务,同时支持联网搜索和多模态交互
Quasar Alpha 是 OpenRouter 推出的预发布 AI 模型,具备百万级 token 上下文处理能力,在代码生成、指令遵循和低延迟响应方面表现卓越,同时支持联网搜索和多模态交互。
1125 1
OpenRouter 推出百万 token 上下文 AI 模型!Quasar Alpha:提供完全免费的 API 服务,同时支持联网搜索和多模态交互