Question

I've been trawling through 1000s of questions and blogs and still don't fully understand dam routing!

Along the lines of Scott Hanselman's blog I am trying to route a certain call to a .GIF to a custom HttpHandler while the rest of the MVC4 site behaves normally. I'm 90% of the way there.

So in the my RouteConfig I have

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.Add("AnalyticsRoute", new Route("analytics/a.gif", new AnalyticsRouteHandler()));
    routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional });
    routes.RouteExistingFiles = true;
}

and in my web.config I have

<handlers>
  ...
  <add name="analytics" verb="*" path="analytics/a.gif" type="Lms.Analytics.AnalyticsHandler, Lms.Analytics" preCondition="managedHandler" />
</handlers>

Now this way, http://mysite.com/analytics/a.gif routes correctly and all is happy, however all my ActionLinks are resolving as http://mysite.com/analytics/a.gif?action=Index&controller=Category

If I reverse the order in the RouteConfig i.e.

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional });
    routes.Add("AnalyticsRoute", new Route("analytics/a.gif", new AnalyticsRouteHandler()));
    routes.RouteExistingFiles = true;
}

All the links resolve just fine, but a call to http://mysite.com/analytics/a.gif results in a 404 error?

I must be doing something stupid and just can't see it?!

Thanks in advance

Was it helpful?

Solution

After finally coming across a similar post, I cracked it. The post was why is the httphandler not running

You need to ignore the path to the file you want the HttpHandler to handle

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.IgnoreRoute("analytics/a.gif");
        routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional });
        routes.RouteExistingFiles = true;
    }

The problem was when I added the web.config and removed the Route.Add I got a 404. I guess the Routing engine was over ruling the Handler.

OTHER TIPS

What you need to do is to create your own custom Route class.

In this class you must override the GetVirtualPath method (on MSDN), which will examine the route data, and generate the right Url. Implement it so that it returns null if your special Url it's not in the provided RequestContext.

What is going on now in your app is that you're using the standard Route class which treat the controller and action in the RouteValue dictionary as overflow paramters, so they're added to the created url.

When you add the route to the route collection use your custom class instead of the default Route class.

More explanation: when you use any method like Url.Action to create a Url, RouteCollection.GetVirtualPath is called. And this method calls the GetVirtualPath of every registered Route, until one of them returns a value different from null (the Url string). As you're not providing your own Route class, the "standard" Route class is being used, and returning the undesired Url. If you create your custom Route class with you own GetVirtualPath implementation you'll return the desired Url.

According to Hanselman's article, you don't want to add a route for your image, you just want to set up the handler in your web.config. Have you tried removing your AnalyticsRoute and see if it works? You may also need to add an ignore route to keep MVC from trying to handle the request.

I haven't used it, but I've heard RouteMagic, written by Phil Haack, is great at troubleshooting route issues.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top