ASP.NET Web API路由系统:路由系统的几个核心类型

时间:2021-11-09 06:39:17

虽然ASP.NET Web API框架采用与ASP.NET MVC框架类似的管道式设计,但是ASP.NET Web API管道的核心部分(定义在程序集System.Web.Http.dll中)已经移除了对System.Web.dll程序集的依赖,实现在ASP.NET Web API框架中的URL路由系统亦是如此。也就是说,ASP.NET Web API核心框架的URL路由系统与ASP.NET本身的路由系统是相对独立的。但是当我们采用基于Web Host的方式(定义在程序集System.Web.Http.WebHost.dll)将ASP.NET Web API承载于一个ASP.NET Web应用的时候,真正实现URL路由的依然是ASP.NET本身的路由系统,Web Host实际上在这种情况下起到了一个“适配”的作用,是两个相对独立的路由系统的“适配器”。我们先来讨论一下实现在ASP.NET Web API框架中这个独立的路由系统是如何设计的。[本文已经同步到《How ASP.NET Web API Works?》]

目录
一、HttpRequestMessage与HttpResponseMessage
二、HttpRouteData
三、HttpVirtualPathData
四、HttpRouteConstraint
五、HttpRoute
六、HttpRouteCollection
七、注册路由映射
八、缺省路由变量

一、HttpRequestMessage与HttpResponseMessage

ASP.NET Web API框架通过具有如下定义的类型HttpRequestMessage表示某个HTTP请求的封装。HttpRequestMessage的属性Method和RequestUri分别表示请求采用的HTTP方法和请求地址,它们可以在相应的构造函数中直接被初始化,而默认采用的HTTP方法为HTTP-GET。

1: public class HttpRequestMessage : IDisposable 2: { 3: public HttpRequestMessage(); 4: public HttpRequestMessage(HttpMethod method, string requestUri); 5: public HttpRequestMessage(HttpMethod method, Uri requestUri); 6:  7: public HttpMethod Method { get; set; } 8: public Uri RequestUri { get; set; } 9: public HttpRequestHeaders Headers { get; } 10: public IDictionary<string, object> Properties { get; } 11: public Version Version { get; set; } 12: public HttpContent Content { get; set; } 13:  14: public void Dispose(); 15: }

只读属性Headers表示的System.Net.Http.Headers.HttpRequestHeaders对象具有一个类似于字典的数据结构,用于存放HTTP请求报头。通过利用字典类型的只读属性Properties,我们可以将任意属性附加到一个HttpRequestMessage对象上。类型为System.Version的Version属性表示请求的HTTP版本,默认采用的HTTP版本为HTTP 1.1(HttpVersion.Version11)。

HttpRequestMessage具有一个Content属性封装了HTTP消息主体相关的信息,其类型为HttpContent。如下面的代码片断所示,HttpContent是一个抽象类,它定义了CopyToAsync和ReadAsByteArrayAsync两组方法进行主体内容的读写操作。HttpContent的Headers属性返回一个System.Net.Http.Headers.HttpContentHeaders对象代表HTTP消息主体内容相关的报头列表,比如表示主题内容编码和长度的“Content-Encoding”和“Content-Length”等。

1: public abstract class HttpContent : IDisposable 2: { 3: //其他成员 4: public Task<byte[]> ReadAsByteArrayAsync(); 5: public Task<Stream> ReadAsStreamAsync(); 6: public Task<string> ReadAsStringAsync(); 7:  8: public Task CopyToAsync(Stream stream); 9: public Task CopyToAsync(Stream stream, TransportContext context); 10:  11: public HttpContentHeaders Headers { get; } 12: }

HTTP响应的基本信息本封装到具有如下定义的HttpResponseMessage类型中。它的RequestMessage表示与之匹配的请求。属性StatusCode和表示响应状态码以及辅助表示响应状态的文字。布尔类型的属性IsSuccessStatusCode用于判断是否属性一个成功的响应,所谓“成功的响应”指的是状态码在范围[200,299]以内的响应。类型为HttpResponseHeaders的属性Headers表示回复消息的HTTP报头列表,而Version代表HTTP消息的版本,默认采用的HTTP版本依然是HTTP 1.1(HttpVersion.Version11)。响应消息主体内容的读取和写入,以及相关内容报头的获取可以通过属性Content表示的HttpContent来完成。

1: public class HttpResponseMessage : IDisposable 2: { 3: //其他成员 4: public HttpRequestMessage RequestMessage { get; set; } 5:  6: public HttpStatusCode StatusCode { get; set; } 7: public string ReasonPhrase { get; set; } 8: public bool IsSuccessStatusCode { get; } 9: public HttpResponseHeaders Headers { get; } 10: public Version Version { get; set; } 11: public HttpContent Content { get; set; } 12: }

二、HttpRouteData