Managing Handler Selection ASP Help

An alternative way to manage request flow is to control the selection of the handler. This allows you to preempt the normal handler selection process or to transfer a request from one handler to another. Table 6-6 puts handler selection in context.

Table 6-6. Putting Handler Selection in Context

Preempting Handler Selection

Preempting the handler selection allows you to explicitly select a handler and bypass the process by which ASP.NET locates a handler for a request. The HttpContext class defines several members that relate to handler selection, as described by Table 6-7. The RemapHandler method allows me to override the normal selection process and explicitly specify the handler that will be used to generate content for the current request.

Table 6-7. The HttpContextMembers That Manage Handler Selection

First, I need to create a handler so that I have something to select with the RemapHandler method. I added a class file called InfoHandler. cs to the Infrastructure folder and used it to define the handler shown in Listing 6-6.

Listing 6-6. The Contents of the InfoHandler.cs File

I can now create a module that explicitly selects the handler for certain requests. I added a class file called HandlerSelectionModule. cs to the Infrastructure folder and used it to define the module shown in Listing 6.7.

Listing 6.7. The Contents of the HandlerSelectionModule.cs File

Tip You can also preempt normal handler selection by using the URL routing system, which calls the RemapHandler method when it matches a request to a route.

I have used the routing values in order to detect requests that target controllers other than Home.For such requests, I preempt the handler selection by calling the RemapHandler method and passing an instance of the handler class that I want to use, which is InfoHandler. I have to call the RemapHandler before the MapRequestHandler event is triggered, so my module is set up to perform its preemption in response to the PostResolveRequestCache event, which preceded MapRequestHandler in the sequence.

In Listing 6-8, you can see that I have registered the module in the Web.config file. I don’t need to register the handler because the module instantiates it directly.

Listing 6-8. Registering a Module in the Web.config File

You can test the selection preemption by starting the application and requesting a URL such as /Test. This request will be matched to the default URL routing configuration in the App_Start/RouteConfig. cs file but doesn’t target the Homecontroller. This means that the HandlerSelectionModule will preempt the normal selection process (which would have led to the MVC framework handler being asked to generate content) and force Info Handler to be used instead, as illustrated by Figure 6-6.

Figure 6-6. Preempting handler selection

Transferring a Request to a Different Handler

Handlers can decide that they are not best suited to generate the content for a request and pass the request on to a different handler for processing. This is equivalent to redirecting a request within ASP.NET without sending a redirection response to the client and is useful when you need finer-grained control over handler selection than is possible through the Web.config registration of handlers. Requests are transferred using the HttpServerUtility. TransferRequest method, which is available in the overloaded versions described by Table 6-8.

Table 6.8. The HttpServerUtility Transferrequest Method

Tip The HttpServerUtility class also defines a Transfer method, but this can be used only with Web Forms and skips a number of the life cycle events after generating content for a request. Use with caution.

To demonstrate the use of the TransferRequest method, I have modified the InfoHandler class from the previous section to transfer the request for a specific URL, as shown in Listing 6-9.

Listing 6-9. Transferring a Request in the InfoHandler.cs File

I decide whether to transfer the request based on the value of the HttpRequest.RawUrl property. In a real project, I tend to use the routing information as demonstrated in the previous section (see Listing 6-7), but I have used the RawUrlproperty for simplicity in this example.

If the URL that has been requested is /Test/Index, then I obtain an instance of the HttpServerUtility class through the HttpContext.Server property and call the TransferRequest method, specifying a URL that will target the MVC framework Homecontroller in the example application. You can see the effect by starting the application and requesting the /Test/Index URL. If you monitor the HTTP requests made by the browser using the F12 developer tools, you will see that no HTTP redirections are sent to the client. Instead, the client requests the /Test/Index URL but gets the content from the /Home/Index URL instead, as shown in Figure 6-7.