【问题标题】:Override MVC routes where applicable without inheriting controller在不继承控制器的情况下覆盖适用的 MVC 路由
【发布时间】:2018-06-14 04:37:35
【问题描述】:

假设我有一个控制器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 中实现。

但是我得到“找不到资源”,我明白为什么,但是我可以在不修改 FooController 的情况下以某种方式解决它吗?

【问题讨论】:

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


    【解决方案1】:

    您可能想看看 HandleUnknownAction()(请参阅 msdn reference page)。

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

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

    可以使用 RedirectToAction() 进行重定向(请参阅msdn reference page

    【讨论】:

    • 请注意,RedirectToAction 会导致向浏览器发送 302 重定向,告诉它在服务器上查找新位置 == 额外的网络往返。
    • 是的,当然是这样。如果您不想要额外的往返,您可能想直接调用控制器方法。我想这个决定取决于具体的用例。 RedirectToAction() 会执行额外的往返(较慢),但可能会导致应用程序中的 url 设计更清晰(每个资源一个 url)。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-13
        • 1970-01-01
        • 2016-07-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多