CHAPTER 9

image

The Anatomy of ASP.NET Web API

This chapter isn’t meant to be read right away. Instead, it contains a number of tables that you can refer to as you read through the chapters that follow. ASP.NET Web API uses a completely different set of namespaces and types than the ones you are familiar with in the MVC framework, and keeping track of which class or interface is responsible for a feature or behavior can be difficult, especially when you start working on your own Web API projects.

Understanding the Web API Namespaces and Types

Web API and the MVC framework share a common heritage and a common design philosophy, but for every important interface and class that you are familiar with in MVC framework development, there is a completely separate counterpart used by Web API. Table 9-1 provides a loose mapping for the ones that you will encounter most often.

Table 9-1. Commonly Used MVC Framework Classes and Their Web API Counterparts

MVC Class or Interface

Web API Equivalent

System.Web.Mvc.IController

System.Web.Http.Controllers.IHttpController

System.Web.Mvc.Controller

System.Web.Http.ApiController

System.Web.HttpContext

System.Web.Http.Controllers.HttpRequestContext

System.Web.HttpRequest

System.Net.Http.HttpRequestMessage

System.Web.HttpResponse

System.Net.Http.HttpResponseMessage

System.Web.HttpApplication

System.Web.Http.HttpConfiguration

The classes and interfaces are equivalent, but there isn’t a one-to-one mapping of methods and properties. In part this is because Web API builds on the System.Net.Http namespace, which was introduced in .NET 4.5 and provides a set of classes that allow any .NET application to support HTTP by providing objects that describe HTTP in a neutral way. Web API uses the types from the System.Net.Http namespace to represent requests and responses (the HttpRequestMessage and HttpResponseMessage classes), HTTP status codes (the HttpStatusCode enum), and HTTP verbs (the HttpMethod class).

Functionality that is specified to Web API is contained in the System.Web.Http namespace and its children, defined as regular interfaces and classes or defined as extension methods that operate on System.Net.Http classes.

Microsoft has avoided the System.Web and System.Web.Mvc namespaces for Web API as part of a gradual effort to rework the ASP.NET platform into something more flexible for web application development and one that can be enhanced independently of the main .NET Framework. At the moment, Web Forms and MVC framework applications get a monolithic block of services through the System.Web assembly, which is shipped as part of the main .NET Framework. The approach that the ASP.NET team is moving toward allows developers to select just the services they want and to have choices about which implementations are used.

You might, for example, decide to use Microsoft’s session state implementation, a third-party logging and tracing implementation, and not to use caching services at all. The engine for this change is a standard called Open Web Interface for .NET (OWIN) that allows more flexibility in how Web API applications are hosted. I describe it in Chapter 26.

For the moment, it is enough to know that Web API doesn’t use the System.Web and System.Web.Mvc namespaces that you are familiar with and that even the most venerable ASP.NET classes, such as HttpRequest and HttpResponse, are not used when developing HTTP web services with Web API. As a quick reference, Table 9-2 lists the main namespaces that you will use during Web API development and where in the book I describe them in detail.

Table 9-2. The Main Web API Namespaces

Namespace

Description

System.Net.Http

This namespace defines types that represent HTTP requests and responses.

System.Net.Http.Formatting

This namespace contains the media type formatters, which are used to serialize data sent to the client and to create model objects from requests. See Chapters 1217 for details.

System.Web.Http

This is the top-level Web API namespace. The most important class for most projects is ApiController, which is the base for Web API controllers and which I describe in Chapter 22, but there are many other useful classes in this namespace.

System.Web.Http.Controllers

This namespace contains the interface that defines a controller (IHttpController) and all of the support classes that the most common controller base class—ApiController—requires. See Chapter 22 for details of how controllers are used in Web API, and see the chapters in this part of the book for details of the features that ApiController brings conveniently together.

System.Web.Http.Dependencies

This namespace contains the classes that provide dependency injection, which I describe in Chapter 10.

System.Web.Http.Dispatcher

This namespace contains the classes that manage the Web API request dispatch process from receiving a request from the hosting platform through to selecting and executing a controller. I describe the dispatch process in Part 3 of this book.

System.Web.Http.Filters

This namespace contains the filters support, which allows for additional logic to be inserted into the dispatch process. I describe filters in Chapters 23 and 24.

System.Web.Http.Metadata

This namespace contains classes that provide descriptions of model classes. These classes are not used directly but are presented through context objects in the dispatch process (which is the topic of Part 3 of this book) or when data provided by a client is being validated (which I describe in Chapter 18).

System.Web.Http.ModelBinding

This namespace contains classes responsible for creating objects and values from HTTP requests that can be used by action methods. I describe the model binding process in Chapter 14 and explain how the process works in detail in Chapters 1517.

System.Web.Http.Results

This namespace contains classes that implement the IHttpActionResult interface, which is used by action methods to describe the responses that will be sent to a client. I describe action method results in Chapter 11.

System.Web.Http.Routing

This namespace contains the Web API URL routing classes, which I describe in Chapters 20 and 21.

System.Web.Http.Validation

This namespace contains the classes that are used to validate data sent from a client, a process I describe in Chapter 18.

System.Web.Http.ValueProviders

This namespace contains classes that are used to retrieve values from requests so that they can be used with action methods. I describe this process in Chapters 1417.

Image Tip  As the table illustrates, there are a lot of Web API namespaces, but many of them contain just a few types, and basic Web API applications can be created with little effort, as I demonstrated in Chapter 2. Even more complicated applications, such as the one I created in Chapters 58, can’t be created using a small number of classes.

WHY CAN’T I USE THE ASP.NET PLATFORM FEATURES ANYWAY?

It often feels like Microsoft makes changes just for the sake of it, and you may have a familiar sinking feeling as you look over the types and namespaces in Tables 9-1 and 9-2, contemplating another steep learning curve.

At this moment, most experienced ASP.NET developers realize that there is a shortcut: use the static HttpContext.Current property to get access to the familiar set of classes provided by the ASP.NET platform, which are still there behind the scenes as long as you are deploying your application to IIS.

Like most shortcuts, you gain in the near term only to pay a price in the long term. You can ignore the System.Net.Http classes, for example, and focus on the classes you know from the System.Web namespace, such as HttpRequest and HttpResponse. And, at first, you will start to produce Web API HTTP web services more quickly and more easily, which is the near-term gain.

The long-term price is that you can’t access advanced Web API features using the old classes and you end up with even more tortured adaptor classes as your Web API needs become more complex. In the end, you’ll spend more time trying to avoid the new Web API classes than it takes to learn how they work. Having two separate sets of namespaces in an application is a little awkward, but my advice is to embrace the change and avoid long-term complexity and maintenance problems.

Understanding the Web API Context Objects

Web API provides a set of objects that provide context about the state of the application and the request that is being handled. The main way you will encounter these objects is through properties defined by the ApiController class, from which Web API controller classes are derived. I describe the role of the ApiController class in more detail in Chapter 22, but Table 9-3 describes the properties it defines that return context objects.

Table 9-3. The Context Properties Defined by the ApiController Class

Name

Description

Configuration

Returns an HttpConfiguration object, which provides information about the configuration of the application. See Chapter 10.

ControllerContext

Returns the HttpControllerContext object that was passed to the controller’s ExecuteAsync method. See Table 9-6.

ModelState

Returns the object used for model binding validation. See Chapter 18.

Request

Returns the HttpRequestMessage that describes the current request. See Table 9-4.

RequestContext

Returns an HttpRequestContext object that provides Web API–specific information about the current request. See Table 9-5.

User

Returns details of the user associated with the current request. See Chapters 5, 23, and 24.

Getting Information About the Request

Requests are represented by the HttpRequestMessage class, which is defined in the System.Net.Http namespace. You are unlikely to need to use the HttpRequestMessage class directly as you start creating simple web services with Web API, but you will begin to use it a lot when you apply some of the more advanced features or begin to customize the way that Web API handles HTTP requests. Table 9-4 describes the properties that the HttpRequestMessage class defines.

Table 9-4. The Properties Defined by the HttpRequestMessage Class

Name

Description

Content

Returns an HttpContent object that contains the content of the HTTP request. Request content is generally accessed through the model binding feature, which I describe in Chapter 14.

Headers

Returns an HttpRequestHeaders object that contains the headers sent by the client. I use request headers to demonstrate several features, including data binding (in Chapter 14) and URL routing (in Chapters 20 and 21).

Method

Returns an HttpMethod object that describes the HTTP method/verb for the request.

Properties

Returns a collection that contains objects provided by the hosting environment or by components that need to communicate with one another. Many of the objects that Web API uses to provide context information define a Properties property, but the only one that I use in this book is the one defined by the HttpRequestMessage object in Chapter 23.

RequestUri

Returns the URL requested by the client, expressed as an Uri object.

Version

Returns the version of HTTP that was used to make the request, expressed as a System.Version object.

The HttpRequestMessage class provides a generalized view of an HTTP request, without any detail that is specific to web services. Web API supplements the HttpRequestMessage class with the HttpRequestContext class, the most important properties of which I describe in Table 9-5.

Table 9-5. The Properties Defined by the HttpRequestContext Class

Name

Description

Configuration

This property returns the HttpConfiguration object associated with the current request. I describe the HttpConfiguration class in Chapter 10 and explain how to apply custom configurations to individual controllers in Chapter 22.

IncludeErrorDetail

This property is used to control the amount of information sent to the client when an exception is thrown and in an action method or filter and left unhandled. See Chapter 25 for details.

IsLocal

This property returns true if the request originates from the local computer.

Principal

This property returns the IPrincipal implementation object that describes the user associated with the request. I used this property in Chapters 6 and 7 for the SportsStore application, and I demonstrate how to create a custom—albeit simple—authentication mechanism in Chapters 23 and 24.

RouteData

This property returns the routing data associated with the request. See Chapters 20 and 21.

Getting Information About the Controller

The HttpControllerContext class provides access to much of the same context data as the HttpRequestContext class but also describes the controller. The similarity between the properties defined by context classes is a facet of the Web API dispatch process, which I describe in Part 3, which doesn’t make assumptions about the controller that will be selected to handle a request—a feature that allows custom controller implementations to be easily created, as I demonstrate in Chapter 22. Some context classes, such as HttpRequestContext, are used more when writing individual web service, and others, such as HttpControllerContext, are more useful when you are customizing the request dispatch process. Table 9-6 lists the properties defined by the HttpControllerContext class.

Table 9-6. The Properties Defined by the HttpControllerContext Class

Name

Description

Configuration

Returns a System.Web.Http.HttpConfiguration object, which provides information about the configuration of the application. See Chapter 10.

Controller

Returns the System.Web.Http.Controllers.IHttpController implementation that is handling the request. See Chapter 22.

ControllerDescriptor

Returns a System.Web.Http.Controllers.HttpControllerDescriptor object that provides information about the controller, which can be used to select controllers to handle a request, as described in Chapter 19.

Request

Returns a System.Net.Http.HttpRequestMessage that provides information about the request being handled. See Table 9-4.

RequestContext

Returns a System.Web.Http.Controllers.HttpRequestContext object that provides Web API–specific information about the request, including details of the user identity associated with the request. See Table 9-5 for details.

RouteData

Returns a System.Web.Http.Routing.IHttpRouteData implementation that provides information about how the request was routed. See Chapters 20 and 21 for details of Web API routing.

Getting Information About Everything Else

The Web API namespaces contain other context objects that are of use only for specific—often advanced—tasks. Rather than list all of their properties here, Table 9-7 describes the classes and references the chapter where I describe each of them in more detail.

Table 9-7. The Web API Context Classes

Name

Description

ExceptionHandlerContext

This class is used to provide context information to global exception handlers. See Chapter 25.

ExceptionLoggerContext

This class is used to provide context information to global exception loggers. See Chapter 25.

HttpActionContext

This class is used to describe an action method and is employed as part of the data binding process. See Chapter 15.

HttpActionDescriptor

This class is used to describe an action method and is employed as part of the data binding process. See Chapter 15.

HttpActionExecutedContext

This class is used to provide context information to exception filters. See Chapter 24.

HttpAuthenticationChallengeContext

This class is used to provide context information to authentication filters. See Chapter 23.

HttpAuthenticationContext

This class is used to provide context information to authentication filters. See Chapter 23.

HttpControllerContext

This class is used to provide a controller with the information it needs to process a request. See Chapter 19.

HttpControllerDescriptor

This class is used during the selection of a controller to process a request. See Chapter 19.

HttpParameterDescriptor

This class is used to describe an action method parameter during the data binding process. See Chapter 15.

HttpRequestContext

This class is used to provide context information about a request. See Table 9-5.

ModelBindingContext

This class is used to provide context information about a model class during the data binding process. See Chapter 16.

Understanding the Web API Components

The basic approach that Web API follows to handle HTTP requests will be familiar from using the MVC framework, but there are a few wrinkles and some important differences to be aware of. In the sections that follow, I briefly describe the major components in a Web API application and explain how they are applied, along with references to the chapters in this book where you can find more information.

Application Configuration

Web API configuration is performed in the App_Start/WebApiConfig.cs file. Add all configuration statements—including those for URL routing—to the Register method, including those that set up URL routes. See Chapter 10 for details of configuring a Web API application and remember not to do any configuration in the Global Application Class (the Global.asax.cs file) because it isn’t supported for all Web API deployment options.

Controllers, Actions, and Results

Web services are defined through controllers. The most common way to create a controller is to derive a class from ApiController, which is defined in the System.Web.Http namespace. The ApiController class provides a number of features that make it simple to create HTTP web services, including action methods, action results, and model binding and validation. I explain how action methods are used to generate results in Chapter 11, how parameters objects and values are created in Chapters 1217, and how to validate data in Chapter 18.

Although the ApiController class is the normal base for controllers, you can also implement your own approach to processing requests by implementing the IHttpController interface. I describe this process in Chapter 22 and explain where controllers fit into the wider dispatch process throughout Part 3 of this book.

Services

ASP.NET Web API defines a set of interfaces and classes that are used to process requests, and these are known as services. Examples include the interfaces that select controllers and action methods, perform model binding, and validate content. The implementations of these interfaces define the infrastructure of a Web API application.

Services are either single-instance or multiple-instance. For single-instance services, there is a single implementation of the service interface used across the entire application. An example of a single-instance service interface is IHttpActionInvoker, which I describe in Chapter 22 and which is responsible for invoking action methods in Web API controllers. There is a default implementation of this interface included in Web API, and you can choose to replace it with a custom implementation, but only one of them will be used to invoke action methods.

For multiple-instance services, several implementations are available, presenting a choice about which one is used. An example is the ModelBinderProvider class, which I describe in Chapter 16 and which provides a model binder for a given type. There are built-in derivations of the ModelBinderProvider class included in Web API, and you can define your own—and at runtime, the combined collection is available so that the most appropriate implementation can be selected and used.

Services are set up and accessed through the HttpConfiguration.Services property; this property returns an instance of the ServicesContainer class, which is defined in the System.Web.Http.Controllers namespace. Table 9-8 shows the methods defined by the ServicesContainer class that are used to register and obtain services.

Table 9-8. The Methods Defined by the ServicesContainer Class

Name

Description

Add(service, impl)

Adds a new implementation of the specified service interface to the collection. There is also an AddRange method that allows multiple implementation objects to be added in a single method call.

AddRange(service, impls)

Adds an enumeration of implementations of the specified interface to the collection.

Clear(service)

Removes all implementations of the specified service interface from the collection.

GetService(service)

Gets an implementation of the specified single-instance service.

GetServices(service)

Gets the implementations of the specified multiple-instance service.

Insert(service, index,     impl)

Inserts an implementation of a multiple-instance service into the collection at a specific index. There is also an InsertRange method that allows multiple implementation objects to be inserted in a single method call.

IsSingleService(service)

Returns true if the specified service interface is single-instance and false if it is a multiple-instance service.

Remove(service, impl)

Removes the specified implementation of a service interface from the collection. There are also RemoveAll and RemoveAt methods that allow multiple implementation objects to be removed or an object at a specified index to be removed.

Replace(service, impl)

Replaces the implementation object for the specified service in the collection. This method works for single- and multiple-instance services.

Image Tip  Implementations of the service interfaces can also be provided through dependency injection, which I describe in Chapter 10.

In addition to the methods described in Table 9-8, Web API provides a set of extension methods that provide strongly typed access to specific services. I describe the most important of these extension methods in Table 9-9, along with details of the service interface they relate to and the chapter of this book where I explain the use of each of them.

Table 9-9. The Extension Methods Defined for the ServicesContainer Class

Name

Description

GetActionInvoker

This method returns an implementation of the IHttpActionInvoker interface, which is responsible for executing an action method. See Chapter 22.

GetActionSelector

This method returns an implementation of the IHttpActionSelector interface, which is responsible for selecting an action method. See Chapter 22.

GetActionValueBinder

This method returns an implementation of the IActionValueBinder interface, which is used to bind values for action method parameters. See Chapter 17.

GetAssembliesResolver

This method returns an implementation of the IAssembliesResolver interface, which is used to locate controller classes when the application starts. See Chapter 19.

GetContentNegotiator

This method returns an implementation of the IContentNegotiator interface, which is used to select a media type formatter to serialize the data in a response. See Chapter 11.

GetExceptionHandler

This method returns an implementation of the IExceptionHandler interface, which is used to define the way that unhandled exceptions are processed to create client responses. See Chapter 25.

GetExceptionLoggers

This method returns all of the registered implementations of the IExceptionLogger interface, which are used to record unhandled exceptions. See Chapter 25.

GetHttpControllerActivator

This method returns an implementation of the IHttpControllerActivator interface, which is used to instantiate controller classes. See Chapter 19.

GetHttpControllerSelector

This method returns an implementation of the IHttpControllerSelector interface, which is used to select controllers. See Chapter 19.

GetHttpControllerTypeResolver

This method returns an implementation of the IHttpControllerTypeResolver, which is used to locate controller classes when the application starts. See Chapter 19.

GetModelBinderProviders

This method returns all of the registered classes that are derived from the abstract ModelBinderProvider class, which are used during the model binding process. See Chapter 16.

GetValueProviderFactories

This method returns all of the registered classes that are derived from the abstract ValueProviderFactory class, which are used during the parameter binding process. See Chapter 15.

Dispatchers and Handlers

Web API has a well-defined model for processing requests, which I describe in Part 3 of this book. There are lots of opportunities for customizing or extending this process, including adding message handlers and changing the way that controllers are selected, instantiated, and executed (all of which I describe in Chapter 19). You can also customize the way that errors are handled (Chapter 25) and inject additional logic into the dispatch process through the use of filters (Chapters 23 and 24).

Summary

In this chapter, I described the components that you will encounter in Web API development, briefly explained what they do, and told you which chapters contain more detailed information. A chapter made up of quick-reference tables does not make for exciting reading, but you will find the information that the tables contain useful as you start to create your own Web API projects because there are a bewildering number of new classes and interfaces to understand. In the next chapter, I show you how to create and configure a Web API application.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.30.62