In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
In this issue, the editor will bring you about how to expand the asynchronous Action function for ASP.NET MVC. The article is rich in content and analyzes and describes for you from a professional point of view. I hope you can get something after reading this article.
Extending the Asynchronous Action function for ASP.NET MVC
A change in the way requests are processed
Before formulating a basic transformation strategy, we need to understand the current architecture of the ASP.NET MVC framework and the request processing process. As follows:
When the application starts (no requests have been accepted at this time), ◆ registers the Route policy for MVC requests with the ASP.NET Routing module. At this point, the RouteHandler attribute in each Route policy (that is, the Route object) is MvcRouteHandler in the ASP.NET MVC framework.
◆ when the ASP.NET Routing module receives a HTTP request that matches a Route policy, it will call the GetHttpHandler of the RouteHandler object in the Route object to get a HttpHandler, which will be executed by ASP.NET. MvcRouteHandler will always return a MvcHandler object.
When ◆ MvcHandler executes, it fetches the controller value from RouteData, builds 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 take the action value from RouteData and give it to the object that implements the IActionInvoker interface to execute an Action.
◆...
If we are going to transform this process into asynchronous processing, we need to make it conform to the asynchronous processing approach in the ASP.NET architecture. ASP.NET architecture for asynchronous request processing can be reflected in several ways, such as asynchronous pages, asynchronous Http Module and so on, and the most suitable approach for the current situation is asynchronous Http Handler. To implement an asynchronous Handler, we need to have the Handler handling the request implement the IHttpAsyncHandler interface instead of the traditional IHttpHandler interface. The BeginProcessRequest and EndProcessRequest methods in the IHttpAsyncHandler interface constitute the APM (Aynchronous Programming Model, Asynchronous programming Model) pattern in .NET, which can be used to process a HTTP request using a "two-segment" asynchronous call.
You should have found that if we want to support asynchronous Action, we must confirm whether to execute an IHttpHandler object or an IHttpAsyncHandler object based on the current request information. In the ASP.NET MVC framework, by default, the controller is checked, constructed, and invoked within the Http Handler (that is, the MvcHandler object). It's too late, and we have to advance the logic to the Routing process. Fortunately, the IRouteHandler supported by ASP.NET Routing is like IHttpHandlerFactory in ASP.NET, which can be executed by generating different Handler depending on the situation. So all we have to do is build a new IRouteHandler type. So AsyncMvcRouteHandler-- was born, and as you can imagine, some of the code is the same as the MvcHandler in the framework, because to some extent we just advance what we were supposed to do 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 get the name of the controller from the controller field of the RouteData and create a controller object that implements the IController interface by registering the Factory on the ControllerBuilder. Since we need to use the ActionInvoker contained in the Controller class to assist in detecting the asynchronous requirements of Action, we will try to convert it to a Controller type. If the conversion is successful, the value of the action field in the RouteData is taken out and the IsAsyncAction method is used to confirm whether the current Action should be executed asynchronously. If so, an AsyncMvcHandler object that implements IHttpAsyncHandler is returned, otherwise a SyncMvcHandler object that implements IHttpHandler is returned.
As for the use of AsyncMvcRouteHandler, simply reset the RouteHandler during MapRoute:
Public static void RegisterRoutes (RouteCollection routes) {routes.IgnoreRoute ("{resource} .axd / {* pathInfo}"); routes.MapRoute ("Default", / / Route name "{controller} / {action} / {id}", / / URL with parametersnew {controller = "Home", action = "Index", id = ""} / / Parameter defaults). RouteHandler = new AsyncMvcRouteHandler ();}
Check if it is an asynchronous Action
We have formed a convention from the above code: if you want to execute an asynchronous Action, the controller object must be of type Controller. The purpose of this convention is to use the IActionInvoker-- contained in the Controller class, to be exact, a function in the ControllerActionInvoker type. Therefore, another convention is that the ActionInvoker object of Controller must return an instance of ControllerActionInvoker.
There are helper methods in ControllerActionInvoker that can return a description object for a Controller or Action. We can get all kinds of information about the Action from an Action description object, and whether it is marked with AsyncActionAttribute is the basis for us to determine whether the Action should be executed asynchronously. As follows:
Private static object s_methodInvokerMutex = new object ()
Private static MethodInvoker s_controllerDescriptorGetter
Internal static bool IsAsyncAction (
Controller controller, string actionName, RequestContext requestContext)
{
Var actionInvoker = controller.ActionInvoker as ControllerActionInvoker
If (actionInvoker = = null) return false
If (s_controllerDescriptorGetter = = null)
{
Lock (s_methodInvokerMutex)
{
If (s_controllerDescriptorGetter = = null)
{
BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic
MethodInfo method = typeof (ControllerActionInvoker). GetMethod (
"GetControllerDescriptor", bindingFlags)
S_controllerDescriptorGetter = new MethodInvoker (method)
}
}
}
Var controllerContext = new ControllerContext (requestContext, controller)
Var controllerDescriptor = (ControllerDescriptor) s_controllerDescriptorGetter.Invoke (
ActionInvoker, controllerContext)
Var actionDescriptor = controllerDescriptor.FindAction (controllerContext, actionName)
Return actionDescriptor = = null? False:
ActionDescriptor.GetCustomAttributes (typeof (AsyncActionAttribute), false. Any ()
}
There is a protected method GetControllerDescriptor in the ControllerActionInvoker type, which takes a parameter of type ControllerContext and returns a ControllerDescriptor object to describe the current controller, from which an ActionDescriptor object can be obtained through the FindAction method to describe the Action to be executed. If it is an Action that does not exist, then returning false,*** performs the default behavior through the SyncMvcHandler object. If and only if there is an AsyncActionAttribute tag on the Action, it should be executed asynchronously and return true. In addition, MethodInvoker is used in this code, which is an auxiliary class, which comes from Fast Reflection Library, which implements the reflection invocation function, but its performance is very close to the direct method call. I described the function and use of this project in detail in this article.
This code involves the improvement of the ASP.NET MVC RC version over the Beta version. In the original ControllerActionInvoker class, there is only the MethodInfo that gets the Action method, and there is no abstract type such as each describing object in RC. From the current design point of view, we are using reflection-based abstract description type subclasses. By default, for example, what we access through the ActionDescriptor abstract type is actually an instance of the ReflectedActionDescriptor type. This is a useful improvement, because we abstract by describing objects, so we can:
◆ uses different implementations to describe objects, using a reflection-based (that is, "convention")-based implementation by default, and we can replace existing implementations with a configuration file-based approach if necessary.
◆ uses the description of a specific object to be free from internal details; for example, an asynchronous Action may consist of two methods.
◆ has a specific description object, and it is also convenient to add additional properties, such as whether the Action should be executed asynchronously, whether Session State should be disabled, and so on.
The above is the editor for you to share how to expand the asynchronous Action function for ASP.NET MVC, if you happen to have similar doubts, you might as well refer to the above analysis to understand. If you want to know more about it, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.