控制器继承并选择哪个控制器具有普遍性

时间:2019-01-10 09:29:52

标签: c# asp.net-mvc inheritance

我有一个基础项目和其他继承项目。基础项目有一些控制器,我可能会偶尔(部分地)继承和覆盖。

基础项目:

public virtual ActionResult Index(string filter = "", int page = 1)

子项目:

public override ActionResult Index(string filter = "", int page = 1)

现在,我更改了routeConfig,因此将路由从正确的名称空间映射到逻辑。

context.MapRoute(
                "Routename",
                "AreaName/{controller}/{action}/{id}",
                new { controller = "ControllerName", action = "Index", id = UrlParameter.Optional },
                new string[] { "ProjectName.Areas.AreaName.SpecificControllers"}
            );

但是,我希望从特定项目中获取新添加的路线(如果存在)。不存在的那些应从基础项目的控制器中获取。 (特定的控制器基本上从空开始,并且仅包含需要覆盖时的方法)。为了尝试实现此功能,我在此处的路由中添加了另一个项目:

 context.MapRoute(
                "Routename",
                "AreaName/{controller}/{action}/{id}",
                new { controller = "ControllerName", action = "Index", id = UrlParameter.Optional },
                new string[] { "ProjectName.Areas.AreaName.SpecificControllers", "ProjectName.Areas.AreaName.GenericControllers"}
            );

但是,这显然会导致以下错误:

Multiple types were found that match the controller named 'MethodName'. This can happen if the route that services this request ('CRM/{controller}/{action}/{id}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.

The request for 'MethodName' has found the following matching controllers:
ProjectName.Areas.AreaName.SpecificControllers.ControllerName
ProjectName.Areas.AreaName.GenericControllers.ControllerName

是否有实现此方法的方法,这样我的路由将始终首先查看特定控制器,并且如果无法在特定控制器中找到该方法,则仅查看通用控制器?

1 个答案:

答案 0 :(得分:0)

据我所知,一般情况下,路由选择基本控制器方法。

没有直接支持来解决您在此问题中提到的问题。

有两种解决方法可以解决此问题。

选项1(我的最爱)::基于管理员的管理和基于继承控制器的路由。

在基本控制器上使用[Area],在继承的控制器上使用[Route]。

我个人喜欢这种方法,因为它可以使控制器内部的代码保持整洁。

[Area("Admin")]
AdminBaseController: Controller { }

[Route("Users"))
UserAdminController : AdminBaseController { }
  • 网址为/ Admin / Users / Action

选项2:在派生的控制器操作中使用特定的路由前缀     [Route(“ Admin”)]     AdminBaseController:控制器{}

public static string UserAdminControllerPrefix = "/Users";
UserAdminController : AdminBaseController { 

[Route(UserAdminControllerPrefix + "/ActionName")]
public void ActionName() {  }

}
  • 形成的URL为/ Admin / Users / ActionName

您可以选择适合您风格的任何选项。 希望这可以帮助。 此答案中提到的两种方法:ASP.NET Core MVC Attribute Routing Inheritance