ASP.NET MVC 3 - 获取当前控制器实例(而非仅仅是名称)

18

我知道如何获取当前控制器的名称

HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString();

但是有没有办法在某个类中(不是在操作或视图中)获取当前的控制器实例?


1
在哪里?在模型中吗?在视图中吗?当然,如果你在一个操作中,你可以使用这个来引用你的控制器,但我猜不是这种情况 :). - BigMike
在某些类中(不在操作或视图中) - Alexandre
由于在MVC模式中,您必须处于某个操作中,除非您在某个数据模型的方法流程或某个帮助程序中。为了避免空引用,我建议为您的类方法添加一个控制器参数,然后跟踪流程开始的位置并将其传递。 - BigMike
你想做什么?我不明白为什么你要这样做,控制器的作用只是处理请求而已。 - Tomas Jansson
2个回答

24

默认情况下,您只能在控制器中使用ControllerContext.Controller或者在视图中使用ViewContext.Context访问当前的Controller。如果您需要从某个类中访问它,则需要实现自定义的ControllerFactory,将控制器实例存储在某个位置,并从该位置检索它。例如,在Request.Items中:

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

然后在你的 Application_Start 方法中注册它:

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

你可以稍后获取控制器实例:

public class SomeClass
{
    public SomeClass()
    {
        var controller = (IController)HttpContext.Current.Items["controllerInstance"];
    }
}

但是我会找到另一种方法来传递控制器实例给我的类,而不是使用这个“hacky”的解决方法。


6
由于某些配置可能导致会话最终存储在数据库中,因此您应该将HttpContext.Current.Session["controllerInstance"]更改为HttpContext.Current.Items["controllerInstance"]。 - John

0

如果我所做的对整个Asp.Net页面生命周期/任何东西有害,请有人指出我的错误,但是你肯定可以做到这一点:

在控制器中

ViewBag.CurrentController = this;

在视图中

var c = ViewBag.CurrentController;
var m1 = BaseController.RenderViewToString(c, "~/Views/Test/_Partial.cshtml", null);

在我的情况下,我有一个所有控制器都扩展的基本控制器。在那个基本控制器中有一个名为RenderViewToString的静态方法,它需要一个控制器。由于我认为此时可以实例化一个空控制器的新实例并将其发送到Asp.Net MVC世界中存在的可爱的ViewBag容器中,因此我只是将其发送到视图中。由于某些原因,我现在无法进入控制器并仅将字符串发送回视图(这是我之前做过的,但要求已更改)。
我这样做的原因是在其他语言(如PHP和JS)中,有类似的简单方法来传输类。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接