5

My question up front

How do I construct a route so that MVC will intercept the classic ASP URL and instead execute an MVC action?

I am migrating a legacy classic ASP application to MVC, and need to have MVC intercept a couple of the legacy ASP URLs because they are major endpoints for external access to the application. But I can't seem to figure out how to do it correctly.

I checked a few other questions and didn't quite find what I'm looking for, but maybe my search-fu is poor today. This one is specific to areas but looks similar to mine which still doesn't work, and this one is a possible workaround but I'd really rather handle this completely within MVC and eliminate the legacy file completely.

What I want to do

Given: /foo/bar.asp

Map to: /InboundLinks/HandleBar

(one URL will be a GET request, but the other will be a POST with some sensitive data, so I need them to be intercepted and the POST data still available to MVC, not sure if a 301 redirect will do that or not)

What I DON'T want to do

I do NOT want to run the classic ASP pages at all. (I'm willing to have it solely do a 301 redirect to the MVC URL if that is the only workaround, but that's it) I want the URLs to be intercepted and handled by MVC. I say this because a few questions I found here and elsewhere seemed to generate some confusion on that point.

What I've already tried

routes.MapRoute(
    name: "LegacyBarUrl",
    url:  "foo/bar.asp",
    defaults: new { controller = "InboundLinks", action = "HandleBar" }
);

But this returns a 404 Not Found error.

Environment

Visual Studio 2013 running in local dev mode on Windows 7. Deployment will be to IIS 7 on a locked down server I don't control, so installing HTTP modules on the server isn't an option unfortunately. The domain will remain the same.

Many thanks in advance for any help/guidance/etc.

Community
  • 1
  • 1
DaveCan
  • 361
  • 1
  • 5
  • 12

2 Answers2

1

What you've tried must work. Make sure it comes at the top of your routing configuration, and the default route comes after it.

public static void RegisterRoutes(RouteCollection routes)
{
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

     routes.MapRoute(
            name: "LegacyBarUrl",
            url:  "foo/bar.asp",
            defaults: new { controller = "InboundLinks", action = "HandleBar" }
            namespaces: new[] { "YourProject.Controllers" }
     );

     routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            namespaces: new[] { "YourProject.Controllers" }
     );
}

EDIT:

OK, I've tried this myself as well and it really does not work. So you have two options:

(1) capture and route your request at the IIS level: If you take this path, this extension might be very helpful: http://www.iis.net/downloads/microsoft/url-rewrite]

(2) write your own RouteBase and redirect legacy routes before MVC looks up the routing table: If you take this path, this article would be very helpful to you (it would be too long to write the code here): http://www.mikesdotnetting.com/article/108/handling-legacy-urls-with-asp-net-mvc

A. Burak Erbora
  • 1,054
  • 2
  • 12
  • 26
  • Yeah that's what I thought too, but unfortunately I'm just getting a 404 for path "/foo/bar.asp". I tried some other paths and for example I can intercept path "/test" but not "/test.asp" which also returns 404. I'm doing local dev without a separate IIS instance but it appears the in-process IIS is configured to look for ASP files as well. So I'll have to see if there is a way to turn that off. – DaveCan Oct 20 '15 at 15:39
  • There is very limited documentation on IIS Express regarding classic ASP, most of it is regarding how to enable debugging. There is a configuration file at `%userprofile%\documents\iisexpress\config\applicationhost.config` that contains several directives for classic ASP. Disabling all of them causes IIS Express not to launch, while leaving the first `section` uncommented allows IIS Express to launch but still looks for `.asp` files instead of using the MVC route. Not sure if it will work differently in the deployed server... – DaveCan Oct 20 '15 at 16:10
  • you might want to check this extension out if you're going for doing the routing at the IIS level: [http://www.iis.net/downloads/microsoft/url-rewrite] – A. Burak Erbora Oct 20 '15 at 17:30
  • updated the answer, and I think those two are your only options. – A. Burak Erbora Oct 20 '15 at 18:04
  • Interesting and thanks for trying again. I also tried `routes.RouteExistingFiles = true` and that didn't work. That setting combined with [this answer](http://stackoverflow.com/a/17123453/4743504) however was _too_ successful, because not only does it intercept the .asp path it also intercepts _all_ static file requests including CSS and images, so it breaks the layout. But the route _does_ work in that case. So it appears I have an all-or-nothing approach. I'll look at the other two links you provided when I'm back at work, maybe I can use one. Will update this question if successful. Thanks! – DaveCan Oct 21 '15 at 01:20
  • Actually I may have just figured it out. Doing both of the configurations mentioned in my previous comment, plus adding `routes.IgnoreRoute("Content/{*relpath}");` seems to both preserve the layout and allow direct file access for CSS/etc while _still_ intercepting the route properly! But this is at home so I'll have to try it again at work tomorrow. Fingers crossed... – DaveCan Oct 21 '15 at 01:26
1

To Anyone running into this problem, the 404 is because the server is looking for the physical file before getting into the routes. What is needed is a handler for the extension, in this case for the classic asp that is going to catch the request so the server doesn't look for the file anymore, and the request is handled by your handler.

Add an entry to the web config file in the handlers section like this:

<add name="ClassicASPHandler" path="*.asp" verb="GET" type="System.Web.Mvc.MvcHttpHandler, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />

Then add the needed route to the configuration routes table. Now, the route will be handled correctly as opposed of looking for the file and returning a 404.

routes.MapRoute(
            name: "LegacyBarUrl",
            url:  "foo/bar.asp",
            defaults: new { controller = "InboundLinks", action = "HandleBar" }
            namespaces: new[] { "YourProject.Controllers" }
     );
Sergio A.
  • 403
  • 2
  • 9