ASP. NET Web API WebHost

Source: Internet
Author: User
Tags webhost

ASP. NET Web API WebHost
Introduction to pipelines and routes in the ASP. NET Web API WebHost host environment

ASP. NET Web API framework is a form of pipelines and routes in the SelfHost environment. This article describes ASP in the WebHost environment. which of the following is the form of pipelines and routes in the NET Web API framework.

 

ASP. NET Web API Routes and Pipelines
  • ASP. NET Web APIExample
  • ASP. NET Web APIRoute object Introduction
  • ASP. NET Web APIMPs Queue Model
  • ASP. NET Web API selfhostPipelines and routes in the host environment
  • ASP. NET Web API webhostPipelines and routes in the host environment

 

ASP. NET Web API webhost Pipelines and routes in the host environment

The following will mainly explain the route registration and execution process (WebHost Environment). The pipeline will not be deliberately described and will be included in the explanation of the route. The splitting will show that the effect is not very good.

 

HttpRoute-> HostedHttpRoute-> HttpWebRoute-> Route

To clearly understand the route Execution Process and pipeline form, you must be familiar with the routing object. NET Web API routing object description only describes the types of routing objects in each environment, and does not explain the transformation process.

Now we will explain the "transformation" Process of the route object.

Sample Code 1-1

  protected void Application_Start(object sender, EventArgs e)
        {
            GlobalConfiguration.Configuration.Routes.MapHttpRoute(
              "DefaultAPI", "api/{controller}/{id}", new { controller="product",id = RouteParameter.Optional });
        }

In the example code 1-1, the route registration is performed in the WebHost environment. According to the MapHttpRoute () method, we can define the extended method type HttpRouteCollectionExtensions of the HttpRouteCollection type, since it is the implementation in the HttpRouteCollectionExtensions type, let's see what the situation is.

Sample Code 1-2

public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints, HttpMessageHandler handler)
        {
            if (routes == null)
            {
                throw System.Web.Http.Error.ArgumentNull("routes");
            }
            HttpRouteValueDictionary dictionary = new HttpRouteValueDictionary(defaults);
            HttpRouteValueDictionary dictionary2 = new HttpRouteValueDictionary(constraints);
            IDictionary<string, object> dataTokens = null;
            HttpMessageHandler handler2 = handler;
            IHttpRoute route = routes.CreateRoute(routeTemplate, dictionary, dictionary2, dataTokens, handler2);
            routes.Add(name, route);
            return route;
        }

We can see that the return type is IHttpRoute, and the generation is implemented by the CreateRoute () method called by the HttpRouteCollection instance. Some friends have to ask, isn't this an implementation method for Route registration in SelfHost? The answer is correct, except that polymorphism is used in the WebHost to return other types. Then let's look at it.

Since we can see the changes here, it means there is a route object that inherits the HttpRouteCollection type and then is created. This is much clearer. In the SelfHost environment, the HttpRouteCollection type exists in the HttpConfiguration type object and is not used independently. And in WebHost.

In this case, let's look back at the definition of the GlobalConfiguration type in code 1-1.

Sample Code 1-3

 
        private static Lazy<HttpConfiguration> _configuration = new Lazy<HttpConfiguration>(delegate {
            HttpConfiguration configuration = new HttpConfiguration(new HostedHttpRouteCollection(RouteTable.Routes));
            configuration.Services.Replace(typeof(IAssembliesResolver), new WebHostAssembliesResolver());
            configuration.Services.Replace(typeof(IHttpControllerTypeResolver), new WebHostHttpControllerTypeResolver());
            configuration.Services.Replace(typeof(IHostBufferPolicySelector), new WebHostBufferPolicySelector());
            return configuration;
        });
        public static HttpConfiguration Configuration
        {
            get
            {
                return _configuration.Value;
            }
        }

From code 1-3, we can see that the _ configuration static variable uses delayed loading. What does it mean that the Configuration Attribute of the HttpConfiguration type below will be instantiated if it is used, this is not the focus.

The key point is that the HostedHttpRouteCollection type route set type object is used as the constructor parameter in the instantiation static variable _ configuration. You can take a look at the internal structure of the HostedHttpRouteCollection.

Now let's go back to the route creation process, as shown in code 1-1 and code 1-2. Actually, the HostedHttpRouteCollection type is used to create a route object. Follow the old rules to see the Implementation Code directly.

Sample Code 1-4

 public override IHttpRoute CreateRoute(string uriTemplate, IDictionary<string, object> defaults, IDictionary<string, object> constraints, IDictionary<string, object> dataTokens, HttpMessageHandler handler)
    {
        return new HostedHttpRoute(uriTemplate, defaults, constraints, dataTokens, handler);
    }

From code 1-4, we can clearly see that the HostedHttpRoute routing object is returned. Let's take a look at the constructor. Only in this way can we know the transformation process.

 public HostedHttpRoute(string uriTemplate, IDictionary<string, object> defaults, IDictionary<string, object> constraints, IDictionary<string, object> dataTokens, HttpMessageHandler handler)
    {
        RouteValueDictionary dictionary = (defaults != null) ? new RouteValueDictionary(defaults) : null;
        RouteValueDictionary dictionary2 = (constraints != null) ? new RouteValueDictionary(constraints) : null;
        RouteValueDictionary dictionary3 = (dataTokens != null) ? new RouteValueDictionary(dataTokens) : null;
        this.OriginalRoute = new HttpWebRoute(uriTemplate, dictionary, dictionary2, dictionary3, HttpControllerRouteHandler.Instance, this);
        this.Handler = handler;
   }

In code 1-4, we only need to pay attention to the value assignment of the OriginalRoute attribute. The OriginalRoute attribute is an attribute of the HostedHttpRoute type and is used to set reference to the Route object, in the example code 1-4, it is also an object of the HttpWebRoute type. The constructor of the HttpWebRoute object is not mentioned here. At this time, we can see that the RouteHandler (Route handler) of the HttpControllerRouteHandler type object is used as the Route (HttpWebRoute) object ).

 

Everyone knows ASP. NET Web API framework depends on ASP in the WebHost environment. the IHttpModule is also used to intercept messages in the early stage. Let's take a look at the code in HttpModule (I think it should be like this. If there is an error, please advise .)

Sample Code 1-5

 public class WebAPIHttpModule:IHttpModule
    {


        public void Dispose()
        {
            throw new NotImplementedException();
        }

        public void Init(HttpApplication context)
        {
            context.PostResolveRequestCache += context_PostResolveRequestCache;
        }

        void context_PostResolveRequestCache(object sender, EventArgs e)
        {
            HttpApplication context = sender as HttpApplication;
            HttpContextWrapper contextWrapper = new HttpContextWrapper(context.Context);
            RouteData routeData = RouteTable.Routes.GetRouteData(contextWrapper);
            RequestContext requestContext=new RequestContext(contextWrapper,routeData);
            IHttpHandler httpHandler = routeData.RouteHandler.GetHttpHandler(requestContext);
            IHttpAsyncHandler httpAsyncHandler = httpHandler as IHttpAsyncHandler;
            httpAsyncHandler.BeginProcessRequest(context.Context, null, null);
        }
     }

From code 1-5, we can see that the RouteData object instance is obtained first to obtain RouteHandler, then IHttpHandler is obtained based on RequestContext, converted to IHttpAsyncHandler type instance, and then its BeginProcessRequest () is called () method to perform the operation.

The above section describes the execution process of the above Code. Some friends may have doubts. How can they get RouteData?

Here I will explain to you that we have such code in code 1-2:

 IHttpRoute route = routes.CreateRoute(routeTemplate, dictionary, dictionary2, dataTokens, handler2);
            routes.Add(name, route);

First, let's take a look at the first sentence. Here, the route mentioned above is the HostedHttpRoute object. There is no doubt that the route object is directly used. Then, let's look at the second sentence. The routes here is the HostedHttpRouteCollection object, however, the direction of adding this Add () method is not the HostedHttpRouteCollection, but the RouteTable we mentioned in the GlobalConfiguration type at the beginning. routes. What is the current environment? ASP. NET Framework environment, right! Undoubtedly, this Add () method adds the aforementioned route (HostedHttpRoute object) to the RouteTable. Routes in the current environment. Some friends may ask about the type error. It is true that the route (HostedHttpRoute object) will be converted into an HttpWebRoute object during addition. The HttpWebRoute object inherits from the Route object. You can refer to the previous sections and we should understand it here. I will not talk about it here.

 

We will go back to code 1-5 and get the IHttpHandler instance through the GetHttphandler () method of RouteHandler after obtaining RouteData. The RouteHandler in RouteData is undoubtedly the HttpControllerRouteHandler type.

Let's take a look at the GetHttphandler () method in the HttpControllerRouteHandler type:

 protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        return new HttpControllerHandler(requestContext.RouteData);
    }

We can see that the last operation is performed by the HttpControllerHandler object type. Let's take a look at the definition of this type:

public class HttpControllerHandler : IHttpAsyncHandler, IHttpHandler

Now you understand why you want to convert it to IHttpAsyncHandler, because if you call a function that implements the IHttpHandler interface, an exception is reported, because the IHttpHandler interface is not implemented in the HttpControllerHandler type, then let's look at the static constructor of the HttpControllerHandler type:

Figure 1


The _ server is of the Lazy <HttpMessageInvoker> type. In the BeginProcessRequest () method, SendAsync () is executed to enter the ASP. NET Web API pipeline.

Next let's take a look at the overall one,

Figure 2

 

Finally, the controller section describes the HttpControllerDispatcher type.

 

 

Author: Jin Yuan

Source: http://www.cnblogs.com/jin-yuan/

The copyright of this article is shared by the author and the blog Park. You are welcome to reprint this article. However, you must keep this statement without the author's consent and go to the Article Page.





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.