ASP.NET MVC model nesting routes

asp.net-mvc, asp.net-mvc-5, asp.net-routing, c#, routes

Solution

Well, it doesn't work the way you're thinking. The reason is that you have two different controllers, `Company` and `Person`. You can't call both of them at the same time.

You are going to have to decide whether you want to edit a person at the `Person` controller, or edit them at the `Company` controller. Personally, I'd edit the person at the person level, but that will mean your `Person.Edit` method will have to take the `companyId` as well as the `personId`.

So you would then create a route like this:

routes.MapRoute(
    "CompanyPerson",                                // Route name
    "Company/{companyId}/Person/{personId}",        // URL with parameters
    new { controller = "Person", action = "Edit" }  // Parameter defaults
);

Then your `Person.Edit` method would look like this:

public ActionResult Edit(int companyId, int personId) {}

EDIT:

You are going to have to use constraints to do what you want.

routes.MapRoute(
    name: "CompanyPerson",
    url: "Company/{companyId}/Person/{personId}/{action}",
    defaults: new { controller = "Person", action = "Index", PersonId = UrlParameter.Optional },
    new {personId = @"\d+" }
);

However, this now means you can do `/Company/7/Person/15/Create`, and that just won't make any sense. The `personId` will simply get ignored.

As for why your Create Link isn't working, is because of the id being before the action. You'll also need another route.

routes.MapRoute(
    name: "CompanyPerson",
    url: "Company/{companyId}/Person/Create",
    defaults: new { controller = "Person", action = "Create" }
);

and this

@Html.ActionLink("Create", "Person", new { companyId = Model.companyId })

It would be a lot easier if you just stuck to the Id after the action. You also need to be careful of capitalizing variable names, as these are C# variables and are case sensitive.

Problem

Consider an ASP.NET MVC application with two models: let's say `Company` and `Person`. Each company has a list of persons. Each person belongs to one company only. If you set up the model and use Visual Studio to generate the controllers/views, you get the ability to edit the companies at `/Company/{id}` etc. and the ability to edit the persons at `/Person/{id}` etc. But I want it to be such that you can only add a person inside a company, i.e. you would edit the persons at `/Company/{id}/Persons/{id}`. How can I set up this sort of routing in ASP.NET MVC 5? EDIT: So I did this in my routes: ``` routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "CompanyPerson", url: "Company/{CompanyId}/Person/{PersonId}/{action}", defaults: new { controller = "Person", action = "Index", PersonId = UrlParameter.Optional } ); routes.MapRoute( name: "Company", url: "Company/{id}/{action}", defaults: new { controller = "Company", action = "Index", id = UrlParameter.Optional } ); routes.MapRoute( name: "Default", url: "{controller}/{action}/", defaults: new { controller = "Home", action = "Index" } ); ``` but it still isn't working. If I go to `/Company/7/Person` I get an index of persons, but `/Company/7/Person/Create` just gives the same index, and the "Create New" link points to `/Person/Create` instead of `/Company/7/Person/Create` Is there just a way to set up all the routes explicitly, like Node or most other MVC frameworks?

Original source