ASP.NET Web API中的Controller
虽然通过Visual Studio向导在ASP.NET Web API项目中创建的 Controller类型默认派生与抽象类型ApiController,但是ASP.NET Web API框架本身只要求它实现IHttpController接口即可,所以我们将其统称为HttpController。既然HttpController指的是所有实现了How ASP.NET Web API Works?》]
1: public interface IHttpController
2: {
3: TaskExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken);
4: }
HttpController可以视为对ASP.NET Web API的消息处理管道的延续。通过“ASP.NET Web API标准的“管道式”设计”的介绍我们知道位于管道末端的是一个HttpRoutingDispatcher对象。当SendAsync方法被执行的时候,HttpRoutingDispatcher会利用隶属于它的HttpControllerDispatcher来激活目标HttpController对象,随后调用该对象的ExecuteAsync方法并将返回的Task一、HttpControllerContext
与HttpMessageHandler的SendAsync方法有所不同,HttpController的ExecuteAsync方法并没有一个表示请求的类型为HttpRequestMessage的参数,取而代之的是一个HttpControllerContext类型的参数。HttpControllerContext定义在命名空间“System.Web.Http.Controllers”下,表示执行HttpController的上下文。
如下面的代码片断所示,通过定义在HttpControllerContext中的属性我们可以得到用于配置消息处理管道的HttpConfiguration对象和封装路由数据的HttpRouteData对象,以及表示当前请求的HttpRequestMessage对象。这三个属性可以在构建HttpControllerContext的时候直接通过构造函数的参数指定,我们也可以先创建一个空的HttpControllerContext对象之后直接对这些属性赋值。
1: public class HttpControllerContext
2: {
3: public HttpControllerContext();
4: public HttpControllerContext(HttpConfiguration configuration, IHttpRouteData routeData, HttpRequestMessage request);
5:
6: public HttpConfiguration Configuration { get; set; }
7: public IHttpRouteData RouteData { get; set; }
8: public HttpRequestMessage Request { get; set; }
9:
10: public IHttpController Controller { get; set; }
11: public HttpControllerDescriptor ControllerDescriptor { get; set; }
12: }
一个HttpControllerContext对象表示执行HttpController的上下文,我们可以通过Controller属性来获取或者设置这个HttpController对象。除此之外,我们还可以利用另一个属性ControllerDescriptor获取或者设置用于描述HttpController的HttpControllerDescriptor对象(类型HttpControllerDescriptor定义在命名空间“System.Web.Http.Controllers”下)。
当执行ApiController的ExecuteAsync方法的时候会抛出如右图所示的InvalidOperation异常,并提示“Cannot reuse an 'ApiController' instance. 'ApiController' has to be constructed per incoming message. Check your custom 'IHttpControllerActivator' and make sure that it will not manufacture the same instance.”错误消息已经表明了ApiController是不能“重用”的,用于处理每一个请求的ApiController都应该是“全新”的。