Request to access the ASP. net mvc Framework, asp. netmvc

Source: Internet
Author: User

Request to access the ASP. net mvc Framework, asp. netmvc

I. Preface

For WebForm development, a request is usually a url Ending with. aspx, which corresponds to a physical file. From the code perspective, it is actually a control (Page ). In MVC, a request corresponds to an Action in the Controller. Anyone familiar with asp.net knows,Asp.net requests are actually handled by HttpHandler.(Implements the IHttpHandler type ). Whether it is an Action in. aspx,. ashx,. asmx, or MVC, the request is sent to HttpHandler. In an MPS queue event, an HttpHandler is created based on the request and its PR method is executed. Aspx and ashx are well understood, because they implement the IHttpHandler interface, while the Controller and Action of MVC have nothing to do with HttpHandler. How does it implement it? Next, let's look at how a request enters the mvc framework.

Ii. Example

Both WebForm and MVC are built on the asp.net platform, and Webform appeared earlier. How does MVC achieve expansion without affecting the underlying framework? This mainly benefits fromRouting Mechanism of asp.net. The routing mechanism does not belong to MVC, and WebForm can also be used. It aims to separate a request from a physical file by ing the request to the specified HttpHandler. For example, we can also set a/Admin/User. aspx? Name = Michael Jacob's request is mapped to/Admin/Michael Jacob with better readability. The following are two url registration methods:

        public static void RegisterRoutes(RouteCollection routes)        {            //MVC            routes.MapRoute(                name: "Default",                url: "{controller}/{action}/{id}",                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }            );            //WebForm            routes.MapPageRoute(                routeName: "WebForm",                routeUrl: "Admin/{user}",                physicalFile: "~/Admin/User.aspx"            );        }

RouteCollection is a set of Route. Route encapsulates routing information such as name, url mode, constraints, and default values. Among them, MapPageRoute is the method defined by RouteCollection, while MapRoute is extended by MVC (the advantage of the extension method is that you can add the required functions without modifying the original code ). They all have the same purpose. Create a Route object and Add it to the set. We can also create a new Route object and then call RouteCollection. Add. The effect is the same. Below we mainly focus on the implementation process of MVC, and WebForm is actually similar.

3. analyze source code

Next we will look at how MVC uses the routing mechanism to achieve expansion. The routing mechanism is throughUrlRoutingModuleComplete, it is an implementationIHttpModuleThe routing module has been registered for us by default. HttpModule registers an HttpApplication event to participate in pipeline processing requests. Specifically, it subscribes to an event of a certain stage of HttpApplication. The routing mechanism uses this principle to subscribe to the UrlRoutingModule.PostResolveRequestCacheEvent to implement url ing. Why is this event? Because the next step of this event is to map the request to the physical file, you must intercept it before. The core code is as follows:

Public class UrlRoutingModule: IHttpModule {public RouteCollection {get {if (_ routeCollection = null) {// global RouteCollection SET _ routeCollection = RouteTable. routes;} return _ routeCollection;} set {_ routeCollection = value;} protected virtual void Init (HttpApplication application) {// register the PostResolveRequestCache event application. postResolveRequestCache + = repository;} private void OnApplicationPostResolveRequestCache (object sender, EventArgs e) {// create context HttpApplication app = (HttpApplication) sender; HttpContextBase context = new HttpContextWrapper (app. context); PostResolveRequestCache (context);} public virtual void PostResolveRequestCache (HttpContextBase context) {// 1. obtain RouteData routeData = RouteCollection. getRouteData (context); if (routeData = null) {return;} // 2. obtain IRouteHandler routeHandler = routeData. routeHandler; if (routeHandler = null) {} // RequestContext ensures the HttpContext and RouteData. In the future, use RequestContext requestContext = new RequestContext (context, routeData); context. request. requestContext = requestContext; // 3. obtain IHttpHandler httpHandler = routeHandler. getHttpHandler (requestContext); // remap to the handler context. remapHandler (httpHandler );}}

We will focus on the main method PostResolveRequestCache. There are three key steps here.

  Step 1. Obtain RouteData

RouteData is the packaging of Route and will be used in subsequent processing. It is obtained through RouteCollection, which is the same set object as the RouteTable. Routes used in the above registration. Calling the RouteCollection GetRouteData will traverse every item of the RouteCollection, that is, the Route object, and then call the GetRouteData method of the Route object (this design is used in many sets of MVC ). The following code:

        public RouteData GetRouteData(HttpContextBase httpContext) {            using (GetReadLock()) {                foreach (RouteBase route in this) {                    RouteData routeData = route.GetRouteData(httpContext);                    if (routeData != null) {                                               return routeData;                    }                }            }            return null;        }

The GetRouteData method of the Route object is as follows:

Public override RouteData GetRouteData (HttpContextBase httpContext) {string requestPath = httpContext. request. appRelativeCurrentExecutionFilePath. substring (2) + httpContext. request. pathInfo; // match url RouteValueDictionary values = _ parsedRoute. match (requestPath, Defaults); if (values = null) {return null;} // wrap it into RouteData. Why is it not placed after if? RouteData routeData = new RouteData (this, RouteHandler); // match the constraint if (! ProcessConstraints (httpContext, values, RouteDirection. incomingRequest) {return null;} // The Values and okokens of RouteData are from Route foreach (var value in values) {routeData. values. add (value. key, value. value);} if (DataTokens! = Null) {foreach (var prop in DataTokens) {routeData. DataTokens [prop. Key] = prop. Value ;}} return routeData ;}

As you can see, the GetRouteData method of the Route object will match the url mode and check the constraints. If it does not match, null is returned. If yes, a new RouteData is created.

  Step 2. Obtain the IRouteHandler interface object

The preceding RouteData is created. The parameters are the current Route object and its RouteHandler attributes. RouteHandler isIRouteHandlerThis is an important interface, which is defined as follows:

    public interface IRouteHandler {        IHttpHandler GetHttpHandler(RequestContext requestContext);    }

Obviously, it is used to obtain IHttpHandler. So where is the RouteHandler attribute of the Route object initialized? Let's go back to the initial registration method, routes. MapRoute. This method creates a Route object based on the passed parameters. The implementation of this method is as follows:

Public static Route MapRoute (this RouteCollection routes, string name, string url, object defaults, object constraints, string [] namespaces) {// create a Route object, its IRouteHandler is MvcRouteHandler Route route = new Route (url, new MvcRouteHandler () {Defaults = defaults (Defaults), Constraints = CreateRouteValueDictionary (constraints ), dataTokens = new RouteValueDictionary ()}; if (namesp Aces! = Null) & (namespaces. length> 0) {route. dataTokens ["Namespaces"] = namespaces;} // register the Route to RouteCollection. add (name, route); return route ;}

When creating a Route, in addition to the url mode,MvcRouteHandlerWhich implements the IRouteHandler interface.
  Step 3. Obtain the IHttpHandler interface object

With MvcRouteHandler, you can call its GetHttpHandler method to obtain IHttpHandler. The implementation of this method is as follows:

Protected virtual IHttpHandler GetHttpHandler (RequestContext requestContext) {// set the session Status requestContext. httpContext. setSessionStateBehavior (GetSessionStateBehavior (requestContext); // return an MvcHandler return new MvcHandler (requestContext) that implements IHttpHandler );}

As you can see, it returnsMvcHandlerMvcHandler implements the IHttpHandler interface. So what I said at the beginning,Requests are actually sent to HttpHandler.In fact, the same is true for MVC. The request is handled by MvcHandler. We can see the definition and main methods of MvcHandler:

Public class MvcHandler: IHttpAsyncHandler, IHttpHandler, listener {protected internal virtual IAsyncResult BeginProcessRequest (HttpContextBase httpContext, AsyncCallback callback, object state) {IController controller; IControllerFactory; // This method will activate the Controller object ProcessRequestInit (httpContext, out controller, out factory); IAsyncController asyncController = controller as IAs YncController; if (asyncController! = Null) {// asynchronous controller BeginInvokeDelegate beginDelegate = delegate (AsyncCallback asyncCallback, object asyncState) {try {// call the Controller BeginExecute method return asyncController. beginExecute (RequestContext, asyncCallback, asyncState);} catch {factory. releaseController (asyncController); throw ;}}; EndInvokeDelegate endDelegate = delegate (IAsyncResult asyncResult) {try {asyncController. endExecute (asyncResult);} finally {factory. releaseController (asyncController) ;}}; SynchronizationContext syncContext = SynchronizationContextUtil. getSynchronizationContext (); AsyncCallback newCallback = AsyncUtil. wrapCallbackForSynchronizedExecution (callback, syncContext); return AsyncResultWrapper. begin (newCallback, state, beginDelegate, endDelegate, _ processRequestTag);} else {// synchronous controller Action action = delegate {try {controller. execute (RequestContext);} finally {factory. releaseController (controller) ;}}; return AsyncResultWrapper. beginSynchronous (callback, state, action, _ processRequestTag );}}}

As you can see, the MvcHandler task is to activate the Controller and Execute its Execute method.This process is very similar to page processing in Webform ,. when the aspx request arrives, the Page implementing IHttpHandler is found based on the virtual path (similar to the routing mechanism finding MvcHandler Based on the url mode), and then the Page cycle is entered (similar to the Mvc activating Controller, then execute the Action process ).

Iv. Summary

Next, let's briefly summarize the process of the request entering the MVC framework:

1. Add the Route object Route to the global RouteCollection. The IRouteHandler of Route is initialized to MvcRouteHandler.

2. UrlRoutingModule registers the HttpApplication PostResolveRequestCache event to intercept requests.

3. When a request arrives, traverse the RouteCollection in the Processing Event and call GetRouteData of each Route object to obtain the RouteData packaging object.

4. Call the GetHttpHandler of MvcRouteHandler to obtain MvcHandler.

5. Call the RemapHandler of HttpContext to map the request to the MvcHandler handler.

6. Execute the MvcHandler PR method, activate the Controller, and execute the Action.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.