Chamaququm
Chamaququm

Reputation: 6728

Controller in Sub Folder

My area is below. Only the concerned part is highlighted.

enter image description here

Route Table

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

    routes.MapRoute(
        "SubFolder", // Route name
        "SubFolder/ChildController",
        new { controller = "ChildController", action = "Index" },
        new[] { "Practise.Areas.SOProblems.Controllers.SubFolder" });


    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}", // URL with parameters
        new { controller = "Home", action = "Index" } // Parameter defaults
    );
}

This only works when the url is like this

localhost:2474/SOProblems/ChildController/index 

This does not works when the url is like this

localhost:2474/SOProblems/SubFolder/ChildController/index

Can you please tell me what is missing?

Upvotes: 25

Views: 39349

Answers (3)

Belmiris
Belmiris

Reputation: 2805

For any future users looking to do this; Look into using Areas. Here's a helpful video. Organizing an application using Areas

Upvotes: 3

Darin Dimitrov
Darin Dimitrov

Reputation: 1038720

This does not works when the url is like this localhost:2474/SOProblems/SubFolder/ChildController/index

That's normal. You route pattern looks like this: SubFolder/ChildController and not SubFolder/ChildController/index. In addition to that you defined your route in the WRONG place. You defined it in your main route definitions and not in your area route definitions. So get rid of the custom route definition from your main routes and add it to the SOProblemsAreaRegistration.cs file (which is where your SOProblems routes should be registered):

public override void RegisterArea(AreaRegistrationContext context)
{
    context.MapRoute(
        "SubFolderRoute", 
        "SOProblems/SubFolder/ChildController",
        new { controller = "ChildController", action = "Index" },
        new[] { "Practise.Areas.SOProblems.Controllers.SubFolder" }
    );

    context.MapRoute(
        "SOProblems_default",
        "SOProblems/{controller}/{action}/{id}",
        new { action = "Index", id = UrlParameter.Optional }
    );
}

Also since your route pattern (SOProblems/SubFolder/ChildController) doesn't have the possibility to specify an action name, you can only have one action on this controller and that would be the default action that you registered (index) in this case.

If you wanted to have more actions on this controller and yet index be the default one you should include that in your route pattern:

context.MapRoute(
    "SubFolder", 
    "SOProblems/SubFolder/ChildController/{action}",
    new { controller = "ChildController", action = "Index" },
    new[] { "Practise.Areas.SOProblems.Controllers.SubFolder" }
);

In both cases your main route definition could remain with their default values:

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

    routes.MapRoute(
        "Default",
        "{controller}/{action}",
        new { controller = "Home", action = "Index" }
    );
}

Upvotes: 18

Matt Houser
Matt Houser

Reputation: 36063

Your new route "SubFolder" does not include the possibility of including an action in the route (in your case, "Index").

Your sample URL

localhost:2474/SOProblems/SubFolder/ChildController/index

Wants to try to match a route like:

"SubFolder/ChildController/{action}"

But you don't include the "{action}" in your route, so it won't match your route. It then tries the default route, which obviously fails.

Try adding "{action}" to your route:

routes.MapRoute(
    "SubFolder", // Route name
    "SubFolder/ChildController/{action}",
    new { controller = "ChildController", action = "Index" },
    new[] { "Practise.Areas.SOProblems.Controllers.SubFolder" });

or take "index" off your test URL.

Upvotes: 6

Related Questions