Recommended Editing:Extension of asynchronous Action for ASP. net mvc)
Change in Request Processing Method
Before formulating basic transformation strategies, we need to understand the current architecture and request processing process of ASP. net mvc framework. As follows:
◆ When the application is started, no request is received.) register the Route policy for the MVC request to the ASP. NET Routing module. In this case, the RouteHandler attribute in each Route policy is the MvcRouteHandler in ASP. net mvc framework.
◆ When ASP. when the NET Routing module receives an HTTP request that matches a specific Route policy, it will call the GetHttpHandler of the RouteHandler object in the Route object to obtain an HttpHandler and submit it to ASP.. NET. MvcRouteHandler will always return an MvcHandler object.
◆ MvcHandler extracts the controller value in RouteData during execution, constructs a controller object that implements the IController interface, and calls the Execute method of the IController interface to Execute the controller.
◆ For an ASP. net mvc application, most controllers will inherit the System. Web. Mvc. Controller type. The Controller class will get the action value from RouteData and hand it to the object implementing the IActionInvoker interface to execute an Action.
◆ ......
If we want to transform this process into asynchronous processing, we need to make it conform to the asynchronous Processing Method in ASP. NET architecture. The ASP. NET architecture can process asynchronous requests in several ways, such as Asynchronous pages and asynchronous Http Module. asynchronous Http Handler is the most suitable method for the current situation. To implement an asynchronous Handler, we need to implement the IHttpAsyncHandler interface for the Handler that processes the request, instead of the traditional IHttpHandler interface. The BeginProcessRequest and EndProcessRequest methods in the IHttpAsyncHandler interface constitute the APMAynchronous Programming Model and asynchronous Programming Model in. NET. You can use the "two-stage" Asynchronous call to process an HTTP request.
You should have discovered that to support asynchronous Action, you must confirm whether to execute an IHttpHandler object or IHttpAsyncHandler object based on the current request information. By default, the ASP. net mvc Framework checks, constructs, and CALLS controllers within Http Handler (MvcHandler object. This is too late. We must talk about these logics before the Routing process. Fortunately, the IRouteHandler supported by ASP. NET Routing is like IHttpHandlerFactory in ASP. NET. Different Handler can be generated as needed for execution. Therefore, we only need to build a new IRouteHandler type. So AsyncMvcRouteHandler was born. As you can imagine, some of the Code is the same as MvcHandler in the framework, to some extent, we did just advance what was originally done in MvcHandler:
public class AsyncMvcRouteHandler : IRouteHandler{ public IHttpHandler GetHttpHandler(RequestContext requestContext) { string controllerName = requestContext.RouteData.GetRequiredString("controller"); var factory = ControllerBuilder.Current.GetControllerFactory(); var controller = factory.CreateController(requestContext, controllerName); if (controller == null) { throw new InvalidOperationException(...); } var coreController = controller as Controller; if (coreController == null) { return new SyncMvcHandler(controller, factory, requestContext); } else { string actionName = requestContext.RouteData.GetRequiredString("action"); return IsAsyncAction(coreController, actionName, requestContext) ? (IHttpHandler)new AsyncMvcHandler(coreController, factory, requestContext) : (IHttpHandler)new SyncMvcHandler(controller, factory, requestContext); } } internal static bool IsAsyncAction( Controller controller, string actionName, RequestContext requestContext) { ... }}
In the GetHttpHandler method, we first obtain the controller name from the controller field of RouteData, and create a controller object that implements the IController interface by registering the Factory on ControllerBuilder. Because we need to use the ActionInvoker included in the Controller class to assist in detecting the asynchronous requirement of Action, we will try to convert it to the Controller type. If the conversion is successful, the value of the action field in RouteData is taken out, and the IsAsyncAction method is used to determine whether the current Action should be executed asynchronously. If yes, an AsyncMvcHandler object implementing IHttpAsyncHandler is returned. Otherwise, a SyncMvcHandler object implementing IHttpHandler is returned.
For the use of AsyncMvcRouteHandler, you only need to reset the Route Handler during MapRoute:
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = "" } // Parameter defaults ).RouteHandler = new AsyncMvcRouteHandler(); }
|