I've created 2 projects:
What I did is I added my custom message handler, derived from DelegatingHandler
to both of them. Here it is:
public class MyHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
return base.SendAsync(request, cancellationToken);
}
}
I registered it in global.asax
in both:
GlobalConfiguration.Configuration.MessageHandlers.Add(new MyHandler());
I put a breakpoint in
return base.SendAsync(request, cancellationToken);
The difference between ASP.NET MVC and ASP.NET WebAPI is that when I call ASP.NET MVC application (http://localhost:4189/Something
) the breakpoint is not triggered. When I call Web API however (http://localhost:7120/api/values
), the breakpoint is triggered.
Why is that? Are there any differences in those application types execution flows?
In addition, when I try to request normal Controller
, not ApiController
of WebAPI application, like http://localhost:7120/Home
, the break point is not triggered.
As shown below in the famous ASP.NET Web API: HTTP Message LIFECYLE
diagram by Microsoft, the ASP.NET Web API has an additional extensibility point known as Message Handlers
(section HTTP Message Handlers
).
So far ASP.NET MVC (5 currently) doesn't provide such extensibility point.
[Link to the full size PDF poster]
The only extensibility point that the MVC and WebAPI share (or at least conceptually) are Filters. Beware that MVC and WebAPI have different ways to register filters and this puts many people in a similar situation as the one you are in right now.
You can compare the route configuration methods of both MVC and WebAPI
For MVC
The available overloads are,
public static class RouteCollectionExtensions
{
public static VirtualPathData GetVirtualPathForArea(this RouteCollection routes, RequestContext requestContext, RouteValueDictionary values);
public static VirtualPathData GetVirtualPathForArea(this RouteCollection routes, RequestContext requestContext, string name, RouteValueDictionary values);
public static void IgnoreRoute(this RouteCollection routes, string url);
public static void IgnoreRoute(this RouteCollection routes, string url, object constraints);
public static Route MapRoute(this RouteCollection routes, string name, string url);
public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults);
public static Route MapRoute(this RouteCollection routes, string name, string url, string[] namespaces);
public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints);
namespaces.
public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, string[] namespaces);
public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces);
}
For WebAPI
public static class HttpRouteCollectionExtensions
{
public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate);
public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults);
public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints);
public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints, HttpMessageHandler handler);
}
See, the last webapi route configuration method has a parameter where you can pass customized HttpMessageHandler you want. MVC routing does not have that provision in its pipeline.
In summation, the MVC execution context and pipeline are totally different from WebAPI due to that fact your break point does not sticks where you want.
Hope helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With