【问题标题】:How to get current controller instance in another class?如何在另一个类中获取当前控制器实例?
【发布时间】:2013-04-04 07:44:04
【问题描述】:

在我的项目中,我在这样的类中管理异常

 public class PortalBusinessExceptionManager
    :IBusinessExceptionManager
{
    public void HandleBusinessException(BusinessExceptionDto exceptionDto)
    {
        //TODO
    }
}

我的项目中有一个BaseController,所有控制器都从它继承

public class BaseController : Controller
{
    public void SetNotification(string message, ExceptionType type)
    {
       //TO DO
    }
}

所以我想在HandleBusinessException 方法中如何从当前控制器获取实例并为其调用SetNotification

 public void HandleBusinessException(BusinessExceptionDto exceptionDto)
{
    var controller=....???
     controller.SetNotification(); 
}

【问题讨论】:

  • 你为什么要使用控制器作为类对象
  • @SatpalSingh 我想在我的异常管理器类中调用 SetNotification 方法
  • 你的控制器不应该有这样的逻辑。您正处于发现Onion Architecture 的风口浪尖上,应该研究一下服务层是什么,以及它应该如何用于keep your controllers thin

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


【解决方案1】:

从这个question 的答案中,您可以创建自己的ControllerFactory 并将控制器实例放入会话中以供以后检索。

public class MyControllerFactory : DefaultControllerFactory
{
    public override IController CreateController(RequestContext requestContext, string controllerName)
    {
        var controller = base.CreateController(requestContext, controllerName);
        HttpContext.Current.Session["controllerInstance"] = controller;
        return controller;
    }
}

然后你在你的 Apllication_Start 中注册它:

ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory());

然后你可以在你的异常处理方法中调用实例。

public void HandleBusinessException(BusinessExceptionDto exceptionDto)
{
     var controller= HttpContext.Current.Session["controllerInstance"] as BaseController;
     if(controller != null) 
     {
         controller.SetNotification(); 
     }
}

请注意,这是一个非常老套的解决方案(例如,会话可能会过期并且您的方法不会被调用),您最好在 BaseController 中覆盖 OnException 方法并在那里调用 SetNotification

public class BaseController : Controller
{
    public void SetNotification(string message, ExceptionType type)
    {
       //TO DO
    }

    protected override void OnException(ExceptionContext filterContext)
    {
        SetNotification(filterContext.Exception.Message, yourExceptionType);
        base.OnException(filterContext);
    }
}

【讨论】:

  • 人们为什么不投票?至少愿意解释一下,我将永远接受争论。我开始觉得人们是故意这样做的。
  • @Valipour HttpContext.Current 本身不是线程安全的。这是一个静态单例。此外,Session 使用起来并不安全,因为它是一个每个用户、每个会话的存储机制,并且这样做可能会阻止您的控制器对象在许多请求中正确处理。这是一个糟糕的答案。
【解决方案2】:

最好放在de HttpContext.Items insted Session

【讨论】:

    【解决方案3】:

    不确定它是否能解决您的问题,但它会有所帮助:

    // get current controller instance
    var controller = DependencyResolver.Current.GetService<MyController>();
    // pass current request context
    controller.ControllerContext = new ControllerContext(Request.RequestContext, controller); 
    // call method
    controller.MethodName();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-02
      • 2015-05-29
      • 1970-01-01
      • 1970-01-01
      • 2014-08-11
      相关资源
      最近更新 更多