ASP.NET MVC 模型嵌套路由

5
考虑一个具有两个模型的ASP.NET MVC应用程序:假设是CompanyPerson。每个公司都有一个人员列表。每个人只属于一个公司。
如果您设置了模型并使用Visual Studio生成控制器/视图,则可以在/Company/{id}等处编辑公司,以及在/Person/{id}等处编辑人员。
但我希望它只能在公司内添加人员,也就是说,您将在/Company/{id}/Persons/{id}处编辑人员。
如何在ASP.NET MVC 5中设置此类路由?
编辑:
因此,我在我的路由中执行了以下操作:
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" }
);

但它仍然无法工作。如果我去 /Company/7/Person,我会得到一个人的索引,但是 /Company/7/Person/Create 只会返回相同的索引,并且 "Create New" 链接指向的是 /Person/Create 而不是 /Company/7/Person/Create
是否有一种设置所有路由的方式,就像 Node 或大多数其他 MVC 框架一样?

所以你只是想把 URL 搞乱吗? - user1666620
是的,这个人应该自动与当前公司关联。 - ian93
1个回答

6

好的,它不是你想象的那样工作。原因是你有两个不同的控制器,CompanyPerson。你不能同时调用这两个控制器。

你需要决定是在 Person 控制器上编辑一个人,还是在 Company 控制器上编辑他们。个人建议在 person 级别上编辑此人,但这意味着你的 Person.Edit 方法需要同时接受 companyIdpersonId 参数。

那么你需要创建如下路由:

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

那么你的 Person.Edit 方法应该像这样:
public ActionResult Edit(int companyId, int personId) {}

编辑:

你需要使用约束条件来实现你想要的效果。

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

然而,这意味着你现在可以执行 /Company/7/Person/15/Create,但这没有任何意义。 personId 将被忽略。
至于为什么你的创建链接不起作用,是因为 id 在操作之前。你还需要另一条路由。
routes.MapRoute(
    name: "CompanyPerson",
    url: "Company/{companyId}/Person/Create",
    defaults: new { controller = "Person", action = "Create" }
);

并且这个

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

如果您只在操作后坚持使用ID,那将会更容易。此外,需要注意变量名称的大小写,因为这些是C#变量且区分大小写。


谢谢。这正是我所想的。 - ian93
抱歉,还不能运行。给我一分钟,我会更新问题。 - ian93
@ian93 - 它不起作用是因为你完全将其更改为其他内容。如果在personId之后有其他内容,你无法使personId可选,匹配模式将无法解决它。 - Erik Funkenbusch
好的,谢谢。我没意识到如果后面还有其他内容就不能将其设为可选项。抱歉! - ian93
@ian93 - 好的,如果您使用约束条件忽略非数字路由(就像我以上所做的那样),则可以这样做。但是,然后您需要一个单独的路由来处理没有id的创建情况。 - Erik Funkenbusch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接