Подтвердить что ты не робот

Asp.net mvc 3- получить текущий экземпляр контроллера (не только имя)

Я знаю, как получить текущее имя контроллера

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

Но есть ли способ получить текущий экземпляр контроллера в некотором классе (не в действии, а не в представлении)?

4b9b3361

Ответ 1

По умолчанию вы можете получить доступ только к текущему Controller внутри контроллера с помощью ControllerContext.Controller или внутри представления с помощью ViewContext.Context. Чтобы получить доступ к нему из какого-либо класса, вам нужно реализовать пользовательский 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"];
    }
}

Но я бы нашел другой способ передать экземпляр контроллера в мой класс вместо этого "хакерского" способа обхода.

Ответ 2

Кто-то должен будет исправить меня, если то, что я делаю, наносит ущерб всему жизненному циклу страницы Asp.Net/независимо, но вы можете это сделать:

В контроллере

ViewBag.CurrentController = this;

В поле зрения

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

В моем случае у меня был базовый контроллер, который расширяют все контроллеры. В этом базовом контроллере существовал статический метод RenderViewToString и требовал от контроллера. Поскольку я решил, что могу просто создать экземпляр пустого контроллера в этот момент для c, я просто отправил его в представление в прекрасном контейнере ViewBag, который существует в мире Asp.Net MVC. По причинам, на которые я не мог сейчас входить, я не мог получить строку в контроллере и отправить ее обратно в представление (это было тем, что я сделал раньше, чем менялись требования).

Причина, по которой я это сделал, - это на других языках, таких как PHP и JS, есть простые способы переноса классов.