重写操作方法上的属性而不必重写整个方法的任何方法

本文关键字:重写 方法 任何 操作方法 属性 不必 | 更新日期: 2023-09-27 18:17:14

我在MVC 5中使用属性路由,但是我已经开始注意到一个痛点。我有一种情况,我想创建一个控制器的子类因为所有的动作都会做同样的事情。然而,我显然需要为子类的操作使用不同的路由。现在,我正在做类似的事情:

public class FooController : Controller
{
    [Route("foo", Name = "Foo")]
    public virtual ActionResult Foo()
    {
        ...
        return View();
    }
}
public class BarController : FooController
{
    [Route("bar", Name = "Bar")]
    public override ActionResult Foo()
    {
        return base.Foo();
    }
}

这对我来说太可怕了。我不会重复实际操作方法的代码(在某些情况下相当多),至少,但这对我来说是错误的。此外,在基本操作方法定义因某种原因而更改的情况下,这将成为维护的噩梦。一般来说,我是否缺少了某种方法,可以在不重写方法的情况下更改属性?也许是特定于路由的属性。还是我运气不好?

重写操作方法上的属性而不必重写整个方法的任何方法

看看这个帖子和答案

多个RoutePrefixes每个控制器使用MVC属性路由?

你可以这样做:

[RoutePrefix("{Type:regex(Foo|Bar)}")]
public class FooController : Controller
{
    [Route("foo", Name = "Foo")]
    public virtual ActionResult Foo()
    {
        ...
        return View();
    }
}

我知道我迟到了一百万年,但我将把两者之间的公共代码抽象到一个抽象控制器类,然后在Foo和Bar控制器上继承这个类。然后你可以重写每个控制器需要不同的方法,并在派生控制器中给它们一个属性,或者不把需要在基控制器类中重写的方法放在一开始。无论如何,我可能会选择路由。与Attribute方式相反,config方式指定路由名。

编辑

你有什么

public class FooController : Controller
{
    [Route("foo", Name = "Foo")]
    public virtual ActionResult Foo()
    {
        ...
    return View();
    }
}
public class BarController : FooController
{
    [Route("bar", Name = "Bar")]
    public override ActionResult Foo()
    {
        return base.Foo();
    }
}

我的建议

public abstract class _baseController : Controller
{
    public ActionResult ActionThatDoesNotNeedToBeOverridden()
    {
        ...
        return View();
    }
    public virtual ActionResult Foo()
    {
        ...
        return View();
    }
}
public class FooController : _baseController
{
    [Route("foo", Name = "Foo")]
    public override ActionResult Foo()
    {
        return base.Foo();
    }
}
public class BarController : _baseController
{
    [Route("bar", Name = "Bar")]
    public override ActionResult Foo()
    {
        return base.Foo();
    }
}

编辑2 你可以这样做,如果你不想重写或麻烦的路由

public class _baseController : Controller
{
    public ActionResult Foo()
    {
        ...
        return View();
    }
}
public class BarController : Controller
{
    public ActionResult Bar()
    {
        var b = new _baseController();
        return b.Foo();
    }
}