Reputation: 71
I developing an Angular 2 spa that will be hosted in an ASP.NET MVC 5 application. I want EVERY request to go to a single route - /home/index - so I've removed the default route and replaced it with a catch-all:
routes.MapRoute(
name: "spa-catch-all",
url: "{*anything}",
defaults: new { controller = "Home", action = "Index" });
This is the ONLY route in the RouteConfig.cs file.
If I hit my application without any path values past the server URL, like this:
http://myserver.org/
Then everything works. If I attempt to hit a URL like this:
http://myserver.org/sectionname
The application returns a 404.
I've installed Phil Haack's Route Debugger NuGet package to try and diagnose this, and the debugger is telling me that the asp.net default route - that I've removed - is matching my url. In fact, I don't even see the catch-all route, at least not as I've defined it (it shows {*catchall} instead of {*anything}) in the "All Routes" table generated by the debugger.
MVC seems to be ignoring my RouteConfig file.
Update 1:
Here's the Complete RouteConfig.cs file: public static void RegisterRoutes(RouteCollection routes)
namespace MyAppNamespace
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "spa-catch-all",
url: "{*anything}",
defaults: new { controller = "Home", action = "Index" });
}
}
}
I do need to point out the following.
Update 2:
In an act of desperation, I went and added two new controllers to match the default route - we'll call them "Path1" and "Path2" - to match the default controller ({controller}/{action}/{id}) that's NOT EVEN IN THE DARN ROUTECONFIG FILE ANYMORE but that MVC still INSISTS on matching. This works for my base cases (http://myapp/path1
and http://myapp/path2
), but it still won't work for subpaths (http://myapp/path1/subpath1
).
I've pretty much determined that either my route configuration is being ignored entirely (no idea why) or the catch all parameters in my paths are simply not working as expected. I'm attaching the global.asax.cs file and the routeconfig.cs file below (as it stands now).
using System;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
namespace MyNamespace
{
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
}
}
using System.Web.Mvc;
using System.Web.Routing;
namespace MyNamespace
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "CatchAll",
url: "{*any}",
defaults: new {controller = "Home", action = "Index", id = UrlParameter.Optional}
);
}
}
}
I'm out of ideas and would love to hear everyone's suggestions.
Update 3:
In an act of further desperation, I've gone an implemented a custom route handler. I don't even care if it works at this point; I just want it to hit a breakpoint when I make a request.
I've created a very simple handler called "SpaRouteHandler" that returns my custom HttpHandler called, creatively, SpaHandler. The SpaHandler, at the moment, doesn't do anything - it just throws an exception. I just want to confirm that the darn thing is being hit.
Here's the latest incarnation of my code:
using System;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
namespace MyNamespace
{
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
}
}
using System.Web.Mvc;
using System.Web.Routing;
namespace MyNamespace
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteValueDictionary defaults = new RouteValueDictionary {{"controller", "Home"}, {"action", "Index"}};
var customRoute = new Route("{*.}", defaults, new SpaRouteHandler());
routes.Add(customRoute);
}
}
}
using System.Web;
using System.Web.Routing;
namespace MyNamespace
{
public class SpaRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new SpaHandler(requestContext);
}
}
}
using System;
using System.Net;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace MyNamespace
{
public class SpaHandler : IHttpHandler
{
public RequestContext LocalRequestContext { get; set; }
public SpaHandler(RequestContext requestContext)
{
LocalRequestContext = requestContext;
}
public bool IsReusable
{
get
{
return false;
}
}
public void ProcessRequest(HttpContext context)
{
throw new NotImplementedException("Just throw an error please");
}
}
}
The exception NEVER gets hit. The good old default route - that's NOT there in the configuration - still appears to work.
What the heck am I doing wrong here?!?!?!?!?
Upvotes: 3
Views: 1585
Reputation: 71
As it turned out, this was a weird one. I had changed the namespace for the web application from when the project was originally created and had used ReSharper's adjust namespaces refactoring tool to adjust the namespaces throughout the project. However, for whatever reason, it didn't change the namespace reference in the Inherits=""
attribute of the <Application />
tag in the global.asax file. It was referencing an old version of the DLL, so my Application_Start wasn't even being called.
Once I changed that reference, everything started working as planned.
Upvotes: 1
Reputation: 10613
Try this:
app.UseMvc(routes =>
{
routes.MapRoute(name:"default", template:"{controller=Default}/{action=Index}/{id?}");
routes.MapRoute("CatchAll", "{*url}", new {controller = "Default", action = "Index"});
});
Upvotes: 1