0

I'm trying to catch "all route" which doesnt have a defined map and redirect to a custom page. This way:

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

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

    routes.MapRoute(
        name: "PageNotFound",
        url: "{*url}",
        defaults: new { controller = "Home", action = "Error" }
    );
}

If I load page that exist in the controller/action domain, it works (i.e. Default run correct). If instead i try to type somethings like "www.mywebsite.com/asd", it doesnt catch the PageNotFound route rules, but instead the framework trigger:

protected void Application_Error()
{

}

Where am I wrong? I want to avoid Application_Error error trigger, and just route to a custom page if (for example) a controller doesnt' exist.

EDIT Code edited after a comment:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

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

routes.MapRoute(
    name: "PageNotFound",
    url: "{*url}",
    defaults: new { controller = "Home", action = "Error" },
    namespaces: new string[] { "MyAppName.Controllers" }
).DataTokens["UseNamespaceFallback"] = false;

Still the same problem.

markzzz
  • 47,390
  • 120
  • 299
  • 507
  • Yes you can. Look at this answer here: https://stackoverflow.com/questions/4612279/asp-net-mvc-default-routes-accessible-via-area-routes - `DataTokens["UseNamespaceFallback"] = false` is the key – Nicola Biada Aug 20 '21 at 10:36
  • @NicolaBiada unfortunately, nope. Adding `.DataTokens["UseNamespaceFallback"] = false;` to the last `MapRoute()` change nothing. The `Application_Error` is still triggered, and no rounting happens. I've edited the question, so you can see what I've edited due to your suggestion. – markzzz Aug 20 '21 at 12:16
  • Are you on MVC .net 4.6.x, right? – Nicola Biada Aug 20 '21 at 12:43
  • yes, but I think you mislead the question :) is not that "found other controllers" outside the scope; instead, i'd like to redirect any request to a custom error page if the framework doesn't find a match (i.e. the controller doesn't exist, as for "/asd"). using "default" on default map is the problematic i think... – markzzz Aug 20 '21 at 12:45
  • 1
    I'll give it a try. Some years ago, when I worked on the framework, I had the same issue and with Useadefault.. parameter resolve the "catch all unrouted". – Nicola Biada Aug 20 '21 at 12:53

1 Answers1

0

After some attempts I have found a partial solution:

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

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

            routes.MapRoute(
                name: "Home_Default",
                url: "Home/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
            
            routes.MapRoute(
                name: "Customer_Default",
                url: "Customer/{action}/{id}",
                defaults: new { controller = "Customer", action = "Index", id = UrlParameter.Optional }
            );

            routes.MapRoute("CatchAll", "{*url}",
                new { controller = "CatchAll", action = "Index" });

...

Now the /abc or /homes route are matched.

Unfortunately the /home/baubau is still unmatched.

You can catch all this error pages via web.config.
At the end of your web.config add:


  <system.webServer>
    <httpErrors errorMode="Custom" existingResponse="Replace">
      <remove statusCode="404" />
      <error statusCode="404" responseMode="ExecuteURL" path="/CatchAll/Index" />
    </httpErrors>
  </system.webServer>
</configuration>
Nicola Biada
  • 2,325
  • 1
  • 8
  • 22
  • It still trigger the Application_Error(), which i dont want. Basically, within Application_Error() i log every error of the app. I just don't want to log these (i.e. when controller doesn't exist) – markzzz Aug 22 '21 at 16:00
  • I think this isn't possible with old framework. Using .net Core you have a lot of new solutions. Can you convert your project to .net Core 3 or .net 5? – Nicola Biada Aug 23 '21 at 06:13
  • I think that's a valid solution to this problem https://stackoverflow.com/a/68657969/365251 – markzzz Aug 23 '21 at 06:46