在适用的情况下覆盖MVC路由而不继承控制器

时间:2018-01-04 12:32:07

标签: asp.net asp.net-mvc asp.net-mvc-routing

假设我有一个控制器FooController,它有一堆操作方法。我想覆盖其中一些方法,但没有一个方法标记为virtual,我不想更改FooController的代码。

所以我实现了一个CustomFooController(不是继承自FooController)并编写了我想要的方法的新版本。

现在我想首先路由到CustomFooController,如果操作不可用,我希望默认为FooController。我已设置此路由配置以覆盖路由:

routes.MapRoute(
    "customFoo",
    "foo/{action}",
    new { controller = "CustomFoo", action = UrlParameter.Optional }
);

以下是一些示例定义:

public class FooController : Controller
{
    public ActionResult Bar { ... }
    public ActionResult Baz { ... }
}

public class CustomFooController : Controller
{
    public ActionResult Bar { ... }
}

因此,在访问/Foo/Bar时,我们应该点击CustomFooController.Bar(),当访问/Foo/Baz时,我们应该点击FooController.Baz(),因为Baz()中没有实现CustomFooController

但是我得到了#34;无法找到资源",我理解为什么,但我可以在不修改FooController的情况下以某种方式解决它吗?

3 个答案:

答案 0 :(得分:1)

您可能想看一下HandleUnknownAction()(参见msdn reference page)。

当请求与控制器匹配时调用它,但在该控制器中找不到具有指定操作名称的方法。

因此,您可以在CustomFooController中重写该方法,以重定向到FooController中的相应操作(甚至是基于您对请求相关数据的自定义检查的其他控制器)。

可以使用RedirectToAction()完​​成重定向(请参阅msdn reference page

答案 1 :(得分:0)

我想我自己找到了一个简洁的解决方案。由于我不想修改FooController和我正在扩展的另一个应用程序中的一堆其他控制器(并依赖于更新),我决定使用MapMvcAttributeRoutes()中的扩展方法System.Web.Mvc.RouteCollectionAttributeRoutingExtensions在我的启动RouteConfig中,以便首先匹配例如路由属性我的CustomFooController优先于传统的路由。

答案 2 :(得分:0)

为了安全起见:HandleUnknownAction()仅在CustomFooController中实现。您不必修改FooController(或其他控制器)。