Як тэлефанаваць іншае дзеянне кантролера ад кантролера ў Mvc

Мне трэба выклікаць кантролер B дзеянне FileUploadMsgView ад кантролера і трэба перадаць параметр для яго.

 Code---its not going to the controller B's FileUploadMsgView().
    In ControllerA
  private void Test()
    {

        try
        {//some codes here
            ViewBag.FileUploadMsg = "File uploaded successfully.";
            ViewBag.FileUploadFlag = "2";

            RedirectToAction("B", "FileUploadMsgView", new { FileUploadMsg = "File   uploaded successfully" });
        }

     In ControllerB receiving part
  public ActionResult FileUploadMsgView(string FileUploadMsg)
    {
         return View();
    }
107
@AndersM. Адказ Эда робіць рэдырэкт. Гэта не тое, што я хачу, калі я знайшоў гэтае пытанне пошуку рашэння.
дададзена аўтар mxmissile, крыніца
@AndersM. Я разумею, што мой каментар фармулёўка была проста дрэнна ... :-) Я павінен падкрэсліць, кропку, якая не была вынікам пажадана.
дададзена аўтар mxmissile, крыніца
кідае выклік канцэпцыі MVC!
дададзена аўтар Stephen Mudere, крыніца
@mxmissile ня быць адказам член, але Эд з'яўляецца тое, што мае патрэбу ў Аскер, так як ён хоча, выгляд, які вярнуўся, заснаваны на тым, што загружаны, я згодны, што які пытаецца мог бы зрабіць лепшую працу па распрацоўцы на яго пытанне (ці з'яўляецца гэта правільнае слова? ) мы не ведаем пра гэта, хоць, як яго англійская можа быць абмежавана, нават калі Tiesons адказ дапамог вам - што добра - гэта не мяняе той факт, што адказ Эда лепш за ўсё адлюстроўвае тое, што патрэбы Аскер
дададзена аўтар Anders M., крыніца
Я ведаю, што гэтае пытанне стары, але на мой погляд, вы павінны адзначыць адказ ад эд капліцы, як лепшы, выглядае tieson як ўзламаць, ён па-ранейшаму ў сіле, але навошта выкарыстоўваць абыходны шлях, калі вы можаце выкарыстоўваць яго так, як гэта павінна было быць і атрымаць жаданы вынік
дададзена аўтар Anders M., крыніца
@AndersM. Аскер прыняў адказ Tieson як лепш, так што я не ведаю, чаму вы вырашылі для яго? Адказ Tieson даў мне дапамог мне больш, чым адказ адказ на гэтае пытанне Эда. ТАК не толькі дапамагае аднаму чалавеку, але кожны, хто мае падобныя праблемы. Дык чаму б не проста трымаць адказ Tieson на вяршыні?
дададзена аўтар Kevin Voorn, крыніца

9 адказы

Як @mxmissile кажа ў каментарах да прынятага адказу, вы не павінны новым да кантролера, паколькі ён будзе адсутнічаць залежнасці, устаноўленыя для IoC і ня будзеце мець HttpContext .

Замест гэтага, вы павінны атрымаць асобнік кантролера, як гэта:

var controller = DependencyResolver.Current.GetService();
controller.ControllerContext = new ControllerContext(this.Request.RequestContext, controller);
136
дададзена
<�Код> кантролер вар будзе прысвоены тып ControllerB , так.
дададзена аўтар DLeh, крыніца
Менавіта тое, што я шукаў. Звярніце ўвагу, што тыя, хто не з дапамогай IoC яшчэ не атрымае HttpContext ўпырскваецца.
дададзена аўтар brichins, крыніца
@ilasno Я іржавы на MVC ў гэтыя дні, але я думаю, што я меў на ўвазе, што вы на самай справе <�я> Папрасіць </я> IoC наладзіць, каб атрымаць цалкам запоўнены аб'ект кантролера (напрыклад, звязаны HttpContext </код >). Я мяркую, што я выкарыстаў гэты падыход без любой IoC, каб атрымаць «неглыбокі» аб'ект кантролера (толькі неабходнага доступу да пэўнай функцыянальнасці) і першапачаткова быў зьбянтэжаны пра тое, чаму часткі былі «адсутнічае». [У бок: я працаваў вакол яго ў той жа час, выкарыстоўваючы гэты падыход, але, верагодна, варта было б рэструктураваць гэтую функцыянальнасць з да агульнага класу.] Што тычыцца налады і выбару IoC, я павінен накіраваць вас на іншыя артыкулы/SO пытанні.
дададзена аўтар brichins, крыніца
вар выступае за ControllerB права?
дададзена аўтар Willa, крыніца
@brichins Ці можаце вы быць больш відавочным, калі вы кажаце, "хто не з дапамогай IoC? Мне цікава, што канкрэтна ўдзельнічае/даступна тут для выбару выкарыстоўваць інверсію кіравання ў гэтым кантэксце, і, такім чынам, пры якіх абставінах можна было б «да гэтага часу не атрымліваю HttpContext ін'екцыі.
дададзена аўтар ilasno, крыніца
@brichins Я думаю, я ў асноўным заклапочаныя HttpContext, і я калі дапусціць (і цяпер тэстуецца :-D), што з дапамогай ліній, указаных у гэтым адказе, кантролер асобнік будзе мець доступ да HttpContext. У мяне няма вопыту выкарыстання IoC ўпырснуць залежнасці праз канструктар кантролера.
дададзена аўтар ilasno, крыніца
Некаторыя людзі захапляюцца бязглуздымі правак ... звярніце ўвагу, што хто-то рэдагаваў адказ зменлівую зменную «кантролер» на «ctrlr» ... так што варта чытаць «ctrlr.ControllerContext = новы ControllerContext (this.Request.RequestContext, Ctrl) ; " калі карыстальнік рэдагаваў яго правільна
дададзена аўтар JoeSharp, крыніца
Даданне controllerContext ў новы асобнік кантролера будзе мець важнае значэнне ў некаторых выпадках. Я вывешваць complemetary адказ.
дададзена аўтар Nishanth Shaan, крыніца
<�Код> ModelState не перадаецца ў кантролер на поўдзень => ён заўсёды будзе пустым і дзейнічае ... што з'яўляецца праблемай.
дададзена аўтар Yepeekai, крыніца
Гэта прымушае мяне блізка, але адна праблема, якая ўзнікае ў тым, што ў маім выпадку, controller.MyAction() робіць спасылку на User.Identity, які аказваецца uininstantiated.
дададзена аўтар Robert H. Bourdeau, крыніца
Гэта выдатна працуе. Дзякуй за абмен
дададзена аўтар Atul Rungta, крыніца
У таргетавання дзеянняў вы павінны выкарыстоўваць вярнуцца View ( "ViewName"); замест гэтага проста вярнуцца View ();
дададзена аўтар mNejkO, крыніца

Кантралёры проста класы - новае адно і выклікаць метад дзеянні гэтак жа, як і любы іншы член класа:

<�Код> Вынік вар = новы ControllerB() FileUploadMsgView ( "некаторая радок") ;.

81
дададзена
Пры выкліку метаду дзеянні такім чынам, вы будзеце абыходзіць усе фільтры дзеянні і іншыя віды паводзінаў, якія вызначаюцца з дапамогай атрыбуту.
дададзена аўтар John Wu, крыніца
Калі вы выкарыстоўваеце IoC, вы можаце атрымаць населеную кантролер праз кантролер вар = DependencyResolver.Current.GetService ();
дададзена аўтар mxmissile, крыніца
@TiesonT. - пагадзіўся. Гэта было б пераважным варыянтам, як супрацьстаяць new'ing іншага кантролера ўверх.
дададзена аўтар JᴀʏMᴇᴇ, крыніца
Ня вы адсутнічаць ControllerContext, запыт і сяброў, калі вы проста гэта зрабіць?
дададзена аўтар cirrus, крыніца
Я паспрабаваў гэта, і я не магу атрымаць новы від, каб паказаць
дададзена аўтар superfly71, крыніца
@cirrus Магчыма. Залежыць ад таго, ці трэба вам што-небудзь іншае, чым вынік ад дзеяння кантролера. Для гэтага канкрэтнага пытання, я думаю, што ОП проста хацеў апрацаваны выгляду з метаду.
дададзена аўтар Tieson T., крыніца
@Valipour Гэта будзе сапраўдны пункт, калі OP выкарыстоўвае IoC, але вы не можаце выказаць здагадку, што з кода, паказанага. Я думаю, адказ Эда Капліцы пазбягае гэтага пытання, хоць.
дададзена аўтар Tieson T., крыніца
@mxmissile Гэта варта дадаць як новы адказ, а не каментаваць.
дададзена аўтар Tieson T., крыніца
@ilasno знаёмыя з тэрмінам «інверсія кіравання» Вы? Справа ў тым, што ён робіць тое, што калі ў вас ёсць кампаненты ў кантролерах, якія павінны быць уведзены ў канструктар, мой адказ не можа працаваць, калі вы не выкарыстоўваеце нешта накшталт DependencyResolver як сэрвіс-лакатар.
дададзена аўтар Tieson T., крыніца
Канкрэтызацыяй кантролера не з'яўляецца добрай ідэяй, таму што гэта жыццёвы цыкл можа кантралявацца іншай частцы прыкладання. напрыклад пры выкарыстанні кантэйнера IoC ўсе depdencies павінны быць уведзеныя, і г.д.
дададзена аўтар Mo Valipour, крыніца
@mxmissile Што канкрэтна робіць «выкарыстоўваючы IoC» азначае ў гэтым кантэксце?
дададзена аўтар ilasno, крыніца
@mxmissile я знаёмы, але не маю досведу працы з ін'екцыйнымі залежнасцямі ў кантролер адмыслова. Я тэстуюць з адказам DLeh ў ніжэй, выкарыстоўвае DependencyResolver.
дададзена аўтар ilasno, крыніца

Ваш ўзор выглядае як псеўда код. Вам трэба вяртанне вынік RedirectToAction :

return RedirectToAction("B", 
                        "FileUploadMsgView",
                        new { FileUploadMsg = "File uploaded successfully" });
55
дададзена
Гэта вяртае 302, які выклікае яшчэ адзін удар на сервер, які не тое, што задае пытанне.
дададзена аўтар rboarman, крыніца
Варта адзначыць, што калі мэта дзеяння прымае толькі POST, гэта не будзе працаваць.
дададзена аўтар Marco Alves, крыніца
@rboarman і я атрымліваю 404
дададзена аўтар usefulBee, крыніца

як кажа @DLeh выкарыстанне даволі

var controller = DependencyResolver.Current.GetService();

Але, даючы кантролер, кантэкст controlller гэта асабліва важна, калі вам трэба атрымаць доступ да User аб'ект, Сервер аб'ект, або HttpContext ўнутры «дзіця» кантролер.

Я дадаў радок кода:

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

ці ж вы маглі б выкарыстоўваць для System.Web Acces бягучага кантэксту таксама доступ Сервер або раннія metioned аб'ектаў

NB: я арыентуюся рамачная версія 4.6 (Mvc5)

13
дададзена
@Steven мне прыйшлося прымяніць гэтыя значэння </гэтага кода> замест кантролер . У канчатковым рахунку, вынік вяртаецца праз лакальны кантролер (гэтага), дык гэта тое, што ў канчатковым выніку спрабуе знайсці выгляд.
дададзена аўтар aaaantoine, крыніца
Калі вы спрабуеце выклікаць ў кантролеры, які выкарыстоўвае View (..) або PartialView (...) вам неабходна ўручную змяніць routeData, так што ASP.NET ведае, як знайсці свой выгляд. <�Код> controller.RouteData.Values ​​[ «кантролер»] = «Галоўная»; controller.RouteData.Values ​​[ «дзеянне»] = «Index»; Мяркуючы, што вы спрабуеце вярнуць вынік ад дзеяння індэкса ў HomeController.
дададзена аўтар Steven, крыніца
Я б таксама дадаць, што Url ўласцівасць не ініцыялізуецца пры DependencyResolver.Current.GetService (). Такім чынам, вы павінны скапіяваць яго з бягучага кантролера ўручную.
дададзена аўтар Ralfeus, крыніца
У таргетавання дзеянняў вы павінны выкарыстоўваць вярнуцца View ( "ViewName"); замест гэтага проста вярнуцца View ();
дададзена аўтар mNejkO, крыніца

Dleh's answer is correct and explain how to get an instance of another controller without missing dependencies set up for IoC

Тым не менш, нам трэба выклікаць метад з гэтага іншага кантролера.
Поўны адказ быў бы:

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

//Call your method
ActionInvoker.InvokeAction(controller.ControllerContext, "MethodNameFromControllerB_ToCall");
2
дададзена

Хай распознаватель аўтаматычна зрабіць гэта.

Ўнутры кантролера:

public class AController : ApiController
{
    private readonly BController _bController;

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

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

}
2
дададзена
имо найчыстая адказ, але вы павінны ўсталяваць кантэкст кантролера ў новы кантролер.
дададзена аўтар Mafii, крыніца

Гэта менавіта тое, што я шукаў пасля таго, як знайсці, што RedirectToAction() не будзе праходзіць складаныя аб'екты класа.

У якасці прыкладу, я хачу, каб выклікаць IndexComparison метад у LifeCycleEffectsResults кантролера і перадаць яго складаны аб'ект класа з імем мадэлі.

Here is the code that failed:

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

Варта адзначыць, што радкі, цэлыя лікі, і г.д. выжывалі паездку да гэтага метаду кантролера, але агульныя аб'екты спісу пакутавалі ад таго, што нагадвала уцечку памяці C.

As recommended above, here's the code I replaced it with:

var controller = DependencyResolver.Current.GetService();

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

Усё працуе, як меркавалася ў цяперашні час. Дзякуем Вам за лідзіруючыя пазіцыі.

1
дададзена
        public ActionResult First_controller()
        {
            return Redirect("~/File_upload/Second_controller");
        }
        public ActionResult Second_controller()
        {
            return View();
        }
1
дададзена

калі праблема заключаецца ў выкліку. Вы можаце выклікаць яго, выкарыстоўваючы гэты метад.

yourController obj= new yourController();

obj.yourAction();
0
дададзена
Пфф! Што рабіць, калі вы чакаеце выніку ад дзеяння замест гэтага? <�Код> вар Рэз = новы ControllerB() SetUpTimer (новы TimeSpan (23, 20, 00)) ;.
дададзена аўтар user5173426, крыніца