- By Dino Esposito
Map of ASP.NET MVC Machinery
Routing is the first step of the longer process that takes an HTTP request to produce a response. The ultimate result of the routing process is the paired controller/action that will process requests not mapped to a physical static file. In Chapter 4, we’ll take a closer look at controller classes—the central console of any ASP.NET MVC applications. Until then, though, an overall look at the entire ASP.NET MVC machinery is in order.
In the rest of the book, in fact, we’ll focus on parts and how to configure and implement them, but it would be nice to see the big picture and analyze how those parts relate to each other (see Figure 3-7).
FIGURE 3-7 The full route of an ASP.NET MVC request
The machinery is triggered by an HTTP request that doesn’t map to a static file. First, the URL goes through the routing system and is mapped to a controller name and an action name.
The Action Invoker
The action invoker is the beating heart of the entire ASP.NET MVC infrastructure and the component that orchestrates all the steps necessary to process a request. The action invoker receives the controller factory and the controller context, a container object populated with route data and HTTP request information. As shown in Figure 3-7, the invoker runs its own pipeline of action filters and provides hooks for some ad hoc application code to run before and after the actual execution of the request.
The invoker uses reflection to create an instance of the selected controller class and to invoke the selected method. In doing so, it also resolves the method’s and constructor’s parameters, reading from the HTTP context, route data, and the system’s DI container.
As we’ll see in the next chapter, any controller method is expected to return an object wrapped in a IActionResult container. As the name suggests, the controller method returns just data to be used for the production of the actual response that will be sent back to clients. In no way is the controller method responsible for writing directly to the response output stream. The controller method does have programmatic access to the response output stream, but the recommended pattern is that the method packages data into an action result object and gives instruction to the invoker on how to further process it.
Processing Action Results
The controller method’s action result is a class that implements the IActionResult interface. The ASP.NET MVC framework defines several such classes for the various types of output a controller method might want to return: HTML, JSON, plain text, binary content, and specific HTTP responses.
The interface has one single method—ExecuteResultAsync—that the action invoker calls to have the data embedded in the specific action result object processed. The ultimate effect of executing an action result is writing to the HTTP response output filter.
Next, the action invoker runs its internal pipeline and calls out the request. The client—most typically the browser—will then receive any generated output.
An action filter is a piece of code that runs around the execution of a controller method. The most common types of action filters are filters that run before or after the controller method executes. For example, you can have an action filter that only adds an HTTP header to a request or an action filter that refuses to run the controller method if the request is not coming via Ajax or from an unknown IP address or referrer URL.
Action filters can be implemented in either of two ways: as method overrides within the controller class or, preferably, as distinct attribute classes. We’ll find out more about action filters in Chapter 4.