Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC Message Handlers vs Web API Message Handlers

I've created 2 projects:

  1. Normal, basic ASP.NET MVC 4 application
  2. Basic ASP.NET WebAPI application

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.

like image 760
Przemysław Kalita Avatar asked Sep 18 '13 19:09

Przemysław Kalita


2 Answers

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]

enter image description here

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.

like image 92
Stoyan Dimov Avatar answered Oct 10 '22 21:10

Stoyan Dimov


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.

like image 40
Dipal Mehta Avatar answered Oct 10 '22 22:10

Dipal Mehta