【问题标题】:Determine which controller/action is invoked in ExecuteCore确定在 ExecuteCore 中调用哪个控制器/动作
【发布时间】:2012-07-04 08:14:38
【问题描述】:

我有一个 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
    }

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

【问题讨论】:

  • 你的系统有授权吗?
  • @alok_dida:是的,授权不是问题。

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


【解决方案1】:

添加新属性

public sealed class SpecialSetUpAttribute : Attribute
{
}

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

基本控制器

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 运行应用程序时,它将执行特殊的设置代码。 我已经为控制器级别实现了此代码。你也可以对动作级别做同样的事情。

【讨论】:

  • 很好,解决方案,但我怎样才能获得动作名称?
  • @SWeko 。我已经为此更新了我的代码。请参阅 BaseController 代码。 (编辑结束和开始。)
【解决方案2】:

我会选择一个稍微不同的方向。

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

所以,

public class UsingSetup1Controller : BaseForSetup1Controller {}

public class UsingSetup2Controller : BaseForSetup2Controller {}

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

[Setup1Initialization]
public class UsingSetup1Controller { }

[Setup2Initialization]
public class UsingSetup2Controller { }

【讨论】:

  • ifs 仅用于跨某些控制器的某些操作。我不希望整个控制器有不同的行为(然后我可以覆盖这些方法),我只想要特定操作的不同行为。
  • 同样,您可以对具有特定行为的操作应用过滤器。
  • 单独的基类不能解决问题,因为大多数控制器都需要两种设置。
猜你喜欢
  • 2010-10-13
  • 2020-03-29
  • 2011-08-23
  • 2018-04-25
  • 1970-01-01
  • 1970-01-01
  • 2013-10-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多