Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Building Web Services with Windows Azure (new)

You're reading from  Building Web Services with Windows Azure (new)

Product type Book
Published in May 2015
Publisher
ISBN-13 9781784398378
Pages 322 pages
Edition 1st Edition
Languages

Table of Contents (17) Chapters

Building Web Services with Microsoft Azure
Credits
About the Authors
About the Reviewers
www.PacktPub.com
Preface
Introduction
Getting Started with the ASP.NET Web API Extending the ASP.NET Web API API Management Developing a Web API for Mobile Apps Connecting Applications with Microsoft Azure Service Bus Creating Hybrid Services Data Services in the Cloud – an Overview of ADO.NET and Entity Framework Data Services in the Cloud – Microsoft Azure Storage Data Services in the Cloud – NoSQL in Microsoft Azure Index

Routing and dispatching


The routing and dispatching stage primarily involves the execution of a series of message handlers, which process the incoming request and then delegate them to the next message handler for processing. In earlier versions of ASP.NET Web API, we could only configure message handlers globally per application. All the message handlers were added to the HttpConfiguration.MessageHandlers collection and were executed for each request. The global configuration was enabled using the Register method in the WebApiConfig.cs file, which gets added when creating a new ASP.NET Web API project. We talk more about the WebApiConfig and Register method in the Creating our first ASP.NET Web API section. The following snippet show a sample Register method definition:

public static void Register(HttpConfiguration config)
{

    config.Routes.MapHttpRoute(
       name: "DefaultApi",
       routeTemplate: "api/{controller}/{id}",
       defaults: new { id = RouteParameter.Optional }
    );
    // add a new message handler to all routes
    config.MessageHandlers.Add(new CustomMessageHandler());
    
}

In the preceding code, we configured CustomMessageHandler() to be called for all routes in the Web API. While this worked well for most basic scenarios, it became a challenge for applications where specialization for a route was required. For example, specific authorization handlers for a route. Web API 2 introduced a per route handler flow that allows granularity when routing requests to message handlers. The following code is added to WebApiConfig.cs to configure a per route custom handler in the ASP.NET Web API 2:

public static void Register(HttpConfiguration config)
{
    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/common/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );

    config.Routes.MapHttpRoute(
        name: "CustomDefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional },
        constraints: null,
        handler: new CustomMessageHandler()
    );
}

In the preceding code, we configured CustomMessageHandler, which inherits from DelegatingHandler to a particular route. We also have a global route with API/common that when called will not invoke our custom message handler, it will rather follow a global configuration. The internals of CustomMessageHandler have been omitted since they are not necessary at this stage; all we are concerned here is how the internal routing logic works. We will discuss these concepts in greater detail in Chapter 2, Extending the ASP.NET Web API.

Let's look at how the per-route message handler routing is performed by ASP.NET Web API 2:

  1. When a request is sent, the host listener (HttpServer) invokes HttpRoutingDispatcher, which acts as the default endpoint message handler. HttpRoutingDispatcher is responsible for discovering the route and invoking the corresponding handlers for the route.

  2. If no route is matched, HttpRoutingDispatcher returns an HTTP standard response code: Not Found (404).

  3. If a route is found, the routing handler checks if there is a handler associated with the current route. It does this by checking the Route.Handler property on the route.

  4. If no handler is specified for the route, it is assumed that the global configuration will be applied, and the request is delegated to HttpControllerDispatcher for further processing.

  5. If a handler is attached to the route, HttpControllerDispatcher attempts to invoke the message handler registered for the particular route. The invoked message handler may then return to the main path and delegate to HttpControllerDispatcher, as shown:

  6. HttpControllerDispatcher is a message handler, which is then responsible for selecting and creating the controller before delegating the request to the controller, as shown:

  7. If no controller is resolved, a 404 status code is returned by HttpControllerDispatcher.

  8. Once the controller is created successfully, its ExecuteAsync is called to delegate processing of the request:

    httpResponseMessage = await controller.ExecuteAsync(controllerContext, cancellationToken);

Controller processing

The final and the most exciting stage of the pipeline is processing the request by the controller; this is where all the magic happens to generate the appropriate response for the incoming request. As explained earlier, if the controller inherits from APIController, much of the plumbing work is already abstracted from the developer. The following pipeline walks through a controller pipeline that inherits from APIController:

  1. The controller first determines the action to be invoked:

    actionDescriptor = ServicesExtensions.GetActionSelector(services).SelectAction(controllerContext);
  2. Next, a series of filters is invoked, which provides authentication and authorization. At any point, if there is a failure response (for example, client not authenticated), the filter can invoke an error response and break the response chain, as shown in the following figure:

  3. The next step is model binding. It is a technique provided by the ASP.NET framework to bind request values to existing models. It is an abstraction layer that automatically populates controller action parameters, taking care of the mundane property mapping and type conversion code typically involved in working with ASP.NET request data. We will explore more about model and parameter binding in Chapter 2, Extending the ASP.NET Web API.

  4. Next, the pipeline executes the actual action and any associated action filters. This will process the code that we write in our action method for processing incoming requests. The framework actually provides an ability to execute the action filters as a pre and post step to the actual method execution.

  5. Once the controller action and the post filters are executed, the final step is to convert the response generated into an appropriate HttpResponseMessage and traverse the chain back to return the response to the client. This is shown in the following figure:

  6. Once HttpResponseMessage has been created, the response traverses back through the pipeline, and is returned to the client as an HTTP response.

You have been reading a chapter from
Building Web Services with Windows Azure (new)
Published in: May 2015 Publisher: ISBN-13: 9781784398378
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime}