ASP.NET MVC - как вызвать действие в контроллере & ldquo; B & rdquo; от контроллера & ldquo; A & rdquo; [Дубликат]

Как насчет

np.unique(itertools.permutations([1, 1, 1]))

Проблема заключается в том, что теперь перестановки представляют собой строки массива Numpy, тем самым используя больше памяти, но вы можете циклически их перемещать по-прежнему

perms = np.unique(itertools.permutations([1, 1, 1]))
for p in perms:
    print p
106
задан Askolein 8 April 2015 в 16:46
поделиться

9 ответов

Контроллеры - это только классы - новый и вызов метода действия, как и любой другой член класса:

var result = new ControllerB().FileUploadMsgView("some string");

82
ответ дан Tieson T. 15 August 2018 в 15:24
поделиться
  • 1
    Разве вы не будете пропускать ControllerContext, Request и друзей, если вы это сделаете? – cirrus 15 October 2013 в 11:37
  • 2
    Реализация контроллера не является хорошей идеей, потому что ее жизненный цикл может контролироваться другой частью приложения. Например. при использовании контейнера IoC все инъекции следует вводить и т. д. – Mo Valipour 25 November 2013 в 18:37
  • 3
    Если вы используете IoC, вы можете получить заполненный контроллер через var controller = DependencyResolver.Current.GetService<ControllerB>(); – mxmissile 12 December 2014 в 18:11
  • 4
    @mxmissile Это стоит добавить как новый ответ, а не комментарий здесь. – Tieson T. 13 December 2014 в 04:15
  • 5
    @ilasno Вы знакомы с термином «инверсия контроля»? То, что он делает, состоит в том, что если у вас есть компоненты в контроллерах, которые необходимо ввести в конструктор, мой ответ действительно не работает, если вы не используете что-то вроде DependencyResolver в качестве локатора службы. – Tieson T. 11 December 2016 в 19:26

Ответ Dleh верен и объясняет, как получить экземпляр другого контроллера без отсутствующих зависимостей, настроенных для IoC

Однако теперь нам нужно вызвать метод из этого другого контроллер. Полный ответ:

var controller = DependencyResolver.Current.GetService<ControllerB>();
controller.ControllerContext = new ControllerContext(this.Request.RequestContext, controller);

//Call your method
ActionInvoker.InvokeAction(controller.ControllerContext, "MethodNameFromControllerB_ToCall");
1
ответ дан AlexB 15 August 2018 в 15:24
поделиться

Это именно то, что я искал после обнаружения того, что RedirectToAction() не будет передавать сложные объекты класса.

В качестве примера я хочу вызвать метод IndexComparison в контроллере LifeCycleEffectsResults и передать ему сложный объект класса с именем model.

Вот неудавшийся код:

return RedirectToAction("IndexComparison", "LifeCycleEffectsResults", model);

Стоит отметить, что строки, целые числа и т. д. выжили в пути к этому методу контроллера, но общие объекты списка страдали от того, что напоминало утечки памяти C.

Как было рекомендовано выше, вот код, который я заменил на него:

var controller = DependencyResolver.Current.GetService<LifeCycleEffectsResultsController>();

var result = controller.IndexComparison(model);
return result;

Все работает как сейчас. Спасибо, что завели путь.

1
ответ дан Andrei 15 August 2018 в 15:24
поделиться

Пусть резольвер автоматически сделает это.

Внутри контроллера A:

public class AController : ApiController
{
    private readonly BController _bController;

    public AController(
    BController bController)
    {
        _bController = bController;
    }

    public httpMethod{
    var result =  _bController.OtherMethodBController(parameters);
    ....
    }

}
2
ответ дан David Castro 15 August 2018 в 15:24
поделиться
  • 1
    imo самый чистый ответ, но вы должны установить контекст контроллера на новый контроллер. – Mafii 26 June 2017 в 13:26

Поскольку @mxmissile говорит в комментариях к принятому ответу, вы не должны вводить новый контроллер, потому что он будет отсутствовать зависимостями, установленными для IoC, и не будет иметь HttpContext.

Вместо этого вы должны получить экземпляр своего контроллера следующим образом:

var controller = DependencyResolver.Current.GetService<ControllerB>();
controller.ControllerContext = new ControllerContext(this.Request.RequestContext, controller);
133
ответ дан JoeSharp 15 August 2018 в 15:24
поделиться
  • 1
    Именно то, что я искал. Обратите внимание, что те, кто не использует IoC, все равно не получат HttpContext. – brichins 28 August 2015 в 21:34
  • 2
    var означает ControllerB правильно? – Willa 2 February 2016 в 14:15
  • 3
    Это закрывает меня, но возникает одна проблема: в моем случае контроллер.MyAction () ссылается на User.Identity, который, как представляется, не является обязательным. – Robert H. Bourdeau 25 May 2016 в 17:10
  • 4
    @ilasno В наши дни я ржавый на MVC, но я думаю, что имел в виду, что на самом деле у меня есть IoC, чтобы получить полностью заполненный объект контроллера (например, связанный с ним HttpContext). Я полагаю, что использовал этот подход без любого IoC, чтобы получить "мелкий" (просто нужен доступ к определенным функциям) и изначально был смущен тем, почему части «отсутствовали». [В стороне: я работал над этим, все еще используя этот подход, но, вероятно, должен был перестроить эту функциональность для общего класса.] Что касается настройки IoC и выбора, я должен был бы отнести вас к другим статьям / SO-вопросам. – brichins 12 December 2016 в 20:59
  • 5
    Некоторые люди увлекаются бессмысленными изменениями ... заметьте, что кто-то редактировал ответ, изменяя переменную «контроллер», к «ctrlr» ... поэтому он должен читать «ctrlr.ControllerContext = new ControllerContext (this.Request.RequestContext, ctrl); & quot; если этот пользователь отредактировал его правильно – JoeSharp 27 December 2017 в 16:10

, поскольку @DLeh говорит, что Use use

var controller = DependencyResolver.Current.GetService<ControllerB>();

Но, давая контроллеру, контекст controlller важен, особенно когда вам нужно получить доступ к объекту User, объекту Server или к HttpContext внутри «дочернего» контроллера.

Я добавил строку кода:

controller.ControllerContext = new ControllerContext(Request.RequestContext, controller);

, иначе вы могли бы использовать System.Web для доступа к текущему контексту, для доступа к Server или ранним меченым объектам

NB: я нацелен на фреймворк версии 4.6 (Mvc5)

13
ответ дан Nishanth Shaan 15 August 2018 в 15:24
поделиться
  • 1
    Если вы попытаетесь вызвать действие в контроллере, который использует View (..) или PartialView (...), вам необходимо вручную изменить routeData, чтобы ASP.NET знал, как найти ваше представление. controller.RouteData.Values["controller"] = "Home";controller.RouteData.Values["action"] = "Index"; Предполагая, что вы пытаетесь вернуть результат из действия Index в HomeController. – Steven 18 June 2016 в 01:28
  • 2
    @Steven Мне пришлось применить эти значения к this, а не к controller. В конечном итоге результат возвращается через локальный контроллер (это), так что это то, что в конечном итоге пытается найти представление. – aaaantoine 29 August 2016 в 13:36
  • 3
    Я добавил бы также, что свойство Url не инициализируется в DependencyResolver.Current.GetService & lt; ControllerB & gt; (). Поэтому вам нужно скопировать его с текущего контроллера вручную. – Ralfeus 7 February 2017 в 11:35
  • 4
    В действии таргетинга вы должны использовать return View("ViewName"); вместо этого только return View(); – mNejkO 13 March 2017 в 00:52

Ваш образец выглядит как псевдокод. Вы должны вернуть результат RedirectToAction:

return RedirectToAction("B", 
                        "FileUploadMsgView",
                        new { FileUploadMsg = "File uploaded successfully" });
53
ответ дан Paul Fleming 15 August 2018 в 15:24
поделиться
  • 1
    Следует отметить, что если целевое действие принимает только POST, это не сработает. – Marco Alves 25 July 2014 в 20:09
  • 2
    Это возвращает 302, что приводит к еще одному попаданию на сервер, который не является тем, что задает вопрос. – rboarman 17 February 2015 в 01:42
  • 3
    @rboarman, и я получаю 404 – usefulBee 16 June 2016 в 17:25
        public ActionResult First_controller()
        {
            return Redirect("~/File_upload/Second_controller");
        }
        public ActionResult Second_controller()
        {
            return View();
        }
0
ответ дан Pramod Variya 15 August 2018 в 15:24
поделиться

, если проблема заключается в вызове. вы можете вызвать его с помощью этого метода.

yourController obj= new yourController();

obj.yourAction();
0
ответ дан user 15 August 2018 в 15:24
поделиться
  • 1
    Пфф! Что делать, если вы ожидаете результата от действия? var res = new ControllerB().SetUpTimer(new TimeSpan(23, 20, 00)); – user5173426 29 March 2018 в 09:49
Другие вопросы по тегам:

Похожие вопросы: