ASP.NET MVC检查是否为异步Action
我们已经形成了一个约定:如果要执行一个异步Action,那么控制器对象必须为Controller类型。这个约定的目的是为了使用Controller类中包含的IActionInvoker——确切地说,是ControllerActionInvoker类型里的功能。因此,另一个约定便是Controller的ActionInvoker对象必须返回一个ControllerActionInvoker的实例。
ControllerActionInvoker中有一些辅助方法,能够返回对于一个Controller或Action的描述对象。从一个Action描述对象中我们可以获取关于这个Action的各种信息,而它是否被标记了AsyncActionAttribute,就是我们判断这个Action是否应该被异步执行的依据。如下:
- publicclassSyncMvcHandler:IHttpHandler,IRequiresSessionState
- {
- publicSyncMvcHandler(
- IControllercontroller,
- IControllerFactorycontrollerFactory,
- RequestContextrequestContext)
- {
- this.Controller=controller;
- this.ControllerFactory=controllerFactory;
- this.RequestContext=requestContext;
- }
- publicIControllerController{get;privateset;}
- publicRequestContextRequestContext{get;privateset;}
- publicIControllerFactoryControllerFactory{get;privateset;}
- publicvirtualboolIsReusable{get{returnfalse;}}
- publicvirtualvoidProcessRequest(HttpContextcontext)
- {
- try
- {
- this.Controller.Execute(this.RequestContext);
- }
- finally
- {
- this.ControllerFactory.ReleaseController(this.Controller);
- }
- }
- }
ControllerActionInvoker类型中有个protected方法GetControllerDescriptor,它接受一个ControllerContext类型的参数,并返回一个ControllerDescriptor对象来描述当前控制器,而从该描述对象中可以通过FindAction方法获得一个ActionDescriptor对象来描述即将执行的Action。如果是一个不存在的Action,那么就返回false,最后就通过SyncMvcHandler对象来执行默认的行为。当且仅当该Action上拥有AsyncActionAttribute 标记时,才说明它应该被异步执行,返回true。此外,这段代码中用到了MethodInvoker,这是一个辅助类,它来源于Fast Reflection Library,它实现了反射调用功能,但是它的性能十分接近于方法的直接调用,我在这篇文章中详细描述了这个项目的功能和使用。
这段代码便涉及到ASP.NET MVC RC版本在Beta版本基础上的改进。在原先的ControllerActionInvoker类中只有获取Action方法的MethodInfo,而没有RC中各描述对象这样的抽象类型。从目前的设计上来看,我们使用的都是基于反射的抽象描述类型的子类。例如默认情况下,我们通过ActionDescriptor抽象类型访问的实际上是ReflectedActionDescriptor类型的实例。这是一个很有用的改进,由于我们通过描述对象进行抽象,于是我们就可以:
使用不同的实现方式来描述各对象,默认情况下是使用基于反射(也就是“约定”)的实现,如果需要的话我们也可以使用基于配置文件的方式替换现有实现。
使用特定对象的描述方式可以不拘泥于内部细节,例如一个异步Action可能就由两个方法组成。
有了特定的描述对象,也方便添加额外的属性,例如该Action是否应该异步执行,是否应该禁用Session State等等。以上介绍ASP.NET MVC执行异步Action
【编辑推荐】