确定在ExecuteCore中调用哪个控制器/操作

时间:2012-07-04 08:14:39

标签: c# .net asp.net-mvc asp.net-mvc-3

我有一个BaseController类,我的所有控制器都继承自该类。它有一个覆盖ExecuteCore方法,可以执行(几乎)所有控制器及其操作所需的初始设置。

    protected override void ExecuteCore()
    {
        SetUpMethod1();
        SetUpMethod2();
        base.ExecuteCore();
    }

    protected virtual void SetUpMethod1()
    {
       //some initialization stuff
    }

    protected virtual void SetUpMethod2()
    {
       //some other initialization stuff
    }

在某些控制器需要一些不同的行为的情况下,很容易覆盖控制器中的相关方法,并且效果很好。但是,来自不同控制器的一些操作在设置方法中需要稍微不同的行为。

我想出了

    protected virtual void SetUpMethod1()
    {
        string controller = (string)ControllerContext.RouteData.Values["controller"]);
        string action = (string)ControllerContext.RouteData.Values["action"]);
        if (controller/account combination is in a list)
            //special setup
        else
            //regular setup
    }

我无法摆脱我做错事的感觉。有没有更好/正确的方法来获得这种行为?

2 个答案:

答案 0 :(得分:1)

添加新属性

public sealed class SpecialSetUpAttribute : Attribute
{
}

我已经定义了两个控制器,其中,我已经为一个控制器定义了这个属性,而没有为其他控制器定义。请参阅下面的代码。

BasicController

public class BasicController : BaseController
    {
        //
        // GET: /Basic/

        public ActionResult Index()
        {
            return View();
        }

}

特殊设置控制器

[SpecialSetUp]
public class HomeController : BaseController
{

}

两个控制器都派生自BaseController。请参阅BaseController的代码。

 public class BaseController : Controller
        {
            protected override void ExecuteCore()
            {
                Type controllerType = this.ControllerContext.Controller.GetType();
                ControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(controllerType);

// Edit start
                string actionName = Convert.ToString(this.ControllerContext.RouteData.Values["action"]);
            string controller = Convert.ToString(this.ControllerContext.RouteData.Values["controller"]);

// Edit end

                if (controllerDescriptor.IsDefined(typeof(SpecialSetUpAttribute), true))
                {
                    //Do special setup
                }
                else
                {
                    //Do normal setup
                }
                base.ExecuteCore();
            }
        }

当您运行BasicController的应用程序时,它将执行正常的设置代码。当您运行HomeController的应用程序时,它将执行特殊的设置代码。 我已经为控制器级别实现了这个代码。你也可以为行动水平做同样的事情。

答案 1 :(得分:0)

我的方向略有不同。

我没有if语句,而是有2个基类:BaseForSetup1Controller,BaseForSetup2Contoller。

所以,

public class UsingSetup1Controller : BaseForSetup1Controller {}

public class UsingSetup2Controller : BaseForSetup2Controller {}

稍微进一步:我更喜欢使用过滤器而不是基类初始化。因此,您可以创建多个初始化过滤器(使用OnActionExecuting方法的操作过滤器)并根据需要在控制器上应用这些过滤器。

[Setup1Initialization]
public class UsingSetup1Controller { }

[Setup2Initialization]
public class UsingSetup2Controller { }