有什么方法可以覆盖action方法的属性而不必覆盖整个方法?

时间:2014-08-08 16:55:55

标签: c# asp.net-mvc asp.net-mvc-5 attributerouting

我在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();
    }
}

这对我来说似乎很糟糕。我不是重复实际操作方法的代码(在某些情况下是相当多的),至少,但这对我来说感觉不对。此外,在基本操作方法定义由于某种原因而发生变化的情况下,这会成为一种维护噩梦。通常,我是否有某些方法可以在不必覆盖方法的情况下更改属性?也许,某些属性特定于路由。或者我只是运气不好?

2 个答案:

答案 0 :(得分:0)

查看此SO帖子并回答

Multiple RoutePrefixes per controller using MVC Attribute routing?

你可以这样做:

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

        return View();
    }
}

答案 1 :(得分:0)

我知道我已经晚了一百万年了,但是我会将两者之间的公共代码抽象为抽象控制器类,然后在你的Foo和Bar控制器上继承该类。然后,您可以覆盖每个控制器需要不同的方法,并在派生控制器中为它们提供属性,或者不要将需要在基本控制器类中重写的方法放在一起。无论如何,我可能会使用Routing.config方式来指定路由名称,例如与Attribute方式相反。

修改

你拥有什么

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();
    }
}