0

I'm in the process of migrating some of our legacy aspx pages to a shiny new MVC based architecture. However, during the transition, I still need to support the old routes, and just either redirect, or render the relevant mvc action.

The issue I have is that 1 aspx that used to handle multiple purposes is now multiple MVC actions.

I figured that I could use a custom RouteBase with:

        routes.Add("legacy", new LegacyPageOverride());

That looks like:

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        if (httpContext.Request.Headers == null)
            return null;

        if (httpContext.Request.Url == null)
            return null;

        if (httpContext.Request.Url.AbsolutePath.StartsWith("/legacy/login/default.aspx", StringComparison.OrdinalIgnoreCase))
            return LoginRoute(httpContext.Request);

        return null;
    }

    private RouteData LoginRoute(HttpRequestBase httpRequestBase)
    {
        if (httpRequestBase?.Url == null)
            throw new ArgumentNullException(nameof(httpRequestBase));

        var routeData = new RouteData(this, new MvcRouteHandler());
        routeData.Values.Add("controller", "Account");

        if (httpRequestBase.Form["SAMLResponse"] != null || 
            httpRequestBase.QueryString["SAMLResponse"] != null)
        {
            routeData.Values.Add("action", "SAML");
        }
        else if (httpRequestBase.QueryString["logged_out"] != null)
        {
            routeData.Values.Add("action", "logoff");
        }
        else
        {
            routeData.Values.Add("action", "SignIn");
        }
        return routeData;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        return null;
    }

I've debugged it through, but although this logic is firing, and GetRouteData is returning a RouteData object, I still receive a 404.

I've tried:

routes.RouteExistingFiles = true (and false).

Deleting the files I'm trying to override the route for.

Trying to remove the staticFile module from the web.config.

I can't use UrlRewriting as I can't get the module installed on all the webservers that host the site. I also need to route based on POST parameters, and have these re-submitted to the resultant page.

UPDATE:

I've narrowed this down to attribute routing. If I disable that on the specific controller action, everything works fine.

So this doesn't work: [Route("login)] public ActionResult Login()

This does: public ActionResult Login()

Any ideas how to make it work? I read something MS_DirectRouteMatches?

Martin
  • 2,180
  • 4
  • 21
  • 41
  • Possible duplicate of [ASP.Net MVC route to catch all *.aspx requests](http://stackoverflow.com/q/36156496/181087). – NightOwl888 May 27 '16 at 21:25
  • Not really, looks like it's maybe attribute routing throwing off the routeData. ps. love MvcSiteMapProvider – Martin May 27 '16 at 21:28
  • Oh, of course - 404. Have you seen [Dots in URL causes 404 with ASP.NET mvc and IIS](http://stackoverflow.com/a/12151501/181087)? Using a `.` in your URL would prevent your request from ever reaching MVC (unless you use `RunAllManagedModulesForAllRequests`, which I wouldn't recommend - better to use a variation of the solution in the accepted answer). – NightOwl888 May 27 '16 at 21:34
  • nope, add the handler, but still getting "The resource cannot be found." tried it in a new solution to role out legacy code. My route is being hit as I can debug, and it returns what I would expect, it just ends with the resource cannot be found message. – Martin May 27 '16 at 21:42
  • even RAMMFAR doesn't help – Martin May 27 '16 at 21:44
  • I was able to confirm your findings. One more piece of information - this only seems to happen when the method you are routing to has `Route` attribute applied. On one hand, this seems like it may be a bug. On the other hand, it doesn't make much sense to return the same controller and action route values from 2 different routes (`RouteAttribute` and `LegacyPageOverride` seem to collide). Furthermore, this whole use case feels like you should be doing a 301 redirect instead of routing directly. But AFAIK you need to use a controller for 301. See link in my first comment for ideas. – NightOwl888 May 28 '16 at 16:24
  • The issue is post data to an endpoint that I can't move, and very old browser support. I thought that simply routing on the backend would allow us to have the old URL, but use an MVC controller/action for it. – Martin May 28 '16 at 22:18
  • In that case, routing is a better choice than redirecting. I suggest you remove the attribute routes from your 3 action methods and route them using convention-based routes - at least it will function. Or, just remove attribute routing altogether - it is pretty limited compared to convention-based routing. You may also want to [report this issue as a bug to the MVC team](https://aspnetwebstack.codeplex.com/workitem/list/basic). – NightOwl888 May 28 '16 at 23:10

0 Answers0