Mvc में एक नियंत्रक से अन्य नियंत्रक कार्रवाई कैसे कॉल करें


153

मुझे नियंत्रक ए से एक नियंत्रक बी कार्रवाई 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();
    }

3
मुझे पता है कि यह सवाल पुराना है, लेकिन मेरी राय में आपको एड चैपल से जवाब को सबसे अच्छा एक के रूप में चिह्नित करना चाहिए, एक हैक की तरह संबंधों का दिखता है, यह अभी भी मान्य है, लेकिन जब आप इसे जिस तरह से उपयोग करना चाहते थे, तो इसका उपयोग क्यों करें? और वांछित परिणाम प्राप्त करें
एंडर्स एम।

1
@AndersM। एड का जवाब एक रीडायरेक्ट करता है। यह नहीं है कि मैं क्या चाहता हूं जब मैंने इस प्रश्न को हल के लिए खोजा।
mxmissile 17

@mxmissile डिक नहीं है, लेकिन एड का जवाब है कि पूछने वाले को क्या चाहिए क्योंकि वह एक ऐसा दृश्य चाहता है जो अपलोड किए जाने के आधार पर लौटा हो, मैं मानता हूं कि पूछने वाला अपने सवाल को तैयार करने के लिए बेहतर काम कर सकता है (क्या यह सही शब्द है? ) हम यह नहीं जान सकते कि यद्यपि उसका अंग्रेजी सीमित हो सकता है, भले ही टायसन जवाब ने आपकी मदद की - जो अच्छा है - यह इस तथ्य को नहीं बदलता है कि एड का उत्तर सबसे अच्छा यह दर्शाता है कि पूछने वाले की क्या आवश्यकता है
एंडर्स एम।

2
@AndersM। मैं समझता हूं, मेरी टिप्पणी का अर्थ सिर्फ बुरा था ... :-) मुझे उस बिंदु पर जोर देना चाहिए था जो मुझे वांछित नहीं था ।
mxmissile

@AndersM। पूछने वाले ने टायसन के उत्तर को सबसे अच्छा माना, इसलिए मुझे यकीन नहीं है कि आप उसके लिए फैसला क्यों करेंगे? जवाब टायसन ने मुझे और अधिक मदद की तो एड का जवाब। एसओ सिर्फ एक व्यक्ति की मदद करने के लिए नहीं है, बल्कि हर किसी के लिए समान समस्याएं हैं। तो क्यों न सिर्फ टायसन के जवाब को शीर्ष पर रखा जाए?
केविन वोर्न

जवाबों:


106

नियंत्रक सिर्फ कक्षा हैं - नया एक और एक्शन विधि को उसी तरह कॉल करें जैसे आप किसी अन्य वर्ग के सदस्य हैं:

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


76
यदि आप ऐसा करते हैं, तो क्या आप नियंत्रक नियंत्रक, अनुरोध और मित्रों को याद नहीं करेंगे?
सिरस

20
नियंत्रक की तात्कालिकता एक अच्छा विचार नहीं है क्योंकि यह जीवन चक्र आवेदन के दूसरे भाग द्वारा नियंत्रित किया जा सकता है। उदाहरण के लिए, आईओसी कंटेनर का उपयोग करते समय सभी अवसादों को इंजेक्ट किया जाना चाहिए, आदि
Mo Valipour

48
यदि आपके आईओसी का उपयोग करते हुए, आप var controller = DependencyResolver.Current.GetService<ControllerB>();
12x14 mxmissile के

3
@mxmissile यहाँ टिप्पणी के बजाय एक नए उत्तर के रूप में जोड़ने लायक है।
टिसन टी।

2
@ilasno आप "नियंत्रण के व्युत्क्रम" शब्द से परिचित हैं? वह जो बिंदु बना रहा है वह यह है कि यदि आपके पास आपके नियंत्रकों में ऐसे घटक हैं जिन्हें निर्माणकर्ता को इंजेक्ट करने की आवश्यकता है, तो मेरा उत्तर वास्तव में काम नहीं करता है, जब तक कि आप एक सेवा-लोकेटर के रूप में डिपेंडेंसीResolver जैसी किसी चीज़ का उपयोग नहीं करते हैं।
टिसन टी।

202

जैसा कि @mxmissile स्वीकृत उत्तर के लिए टिप्पणियों में कहता है, आपको नियंत्रक को नया नहीं करना चाहिए क्योंकि यह आईओसी के लिए सेट की गई निर्भरता गायब होगी और उसके पास नहीं होगी HttpContext

इसके बजाय, आपको इस तरह अपने नियंत्रक का एक उदाहरण मिलना चाहिए:

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

ठीक वही जो मेरे द्वारा खोजा जा रहा था। ध्यान दें कि IoC का उपयोग नहीं करने वालों को अभी भी HttpContextइंजेक्शन नहीं मिलेगा ।
ब्रिचिंस

var controllerटाइप किया जाएगा ControllerB, हाँ।
DLeh 14

1
यह मुझे बंद कर देता है, लेकिन एक समस्या जो उत्पन्न होती है, वह यह है कि मेरे मामले में, नियंत्रक। मायएक्शन () User.Identity का संदर्भ देता है, जो कि uininstantiated प्रतीत होता है।
रॉबर्ट एच। बोर्देउ

1
@ilasno मैं इन दिनों MVC पर जंग खा रहा हूं, लेकिन मुझे लगता है कि मेरा मतलब था कि आपके पास वास्तव में पूरी तरह से आबादी वाले नियंत्रक ऑब्जेक्ट (जैसे एक संबद्ध HttpContext) प्राप्त करने के लिए IoC है । मेरा मानना ​​है कि मैंने "उथले" नियंत्रक ऑब्जेक्ट (बस कुछ कार्यक्षमता तक पहुंच की आवश्यकता) पाने के लिए किसी भी आईओसी के बिना इस दृष्टिकोण का उपयोग किया और शुरू में इस बारे में उलझन में था कि भागों "गायब" क्यों थे। [एक तरफ: मैंने अभी भी इस दृष्टिकोण का उपयोग करते हुए इसके चारों ओर काम किया, लेकिन संभवत: उस कार्यक्षमता को एक साझा वर्ग के लिए हटा दिया जाना चाहिए।] IoC सेटअप और विकल्पों के रूप में, मुझे आपको अन्य लेखों / SO प्रश्नों का उल्लेख करना होगा।
ब्रिचिंस

3
कुछ लोग व्यर्थ संपादन के साथ दूर हो जाते हैं ... ध्यान दें कि किसी ने उत्तर "एडिटिव" को "ctrlr" में बदलते हुए संपादित किया ... इसलिए इसे "ctrlr.ControllerContext = new ControllerContext (यह .Request.RequestContext, ctrl) पढ़ना चाहिए" , " यदि उस उपयोगकर्ता ने इसे सही ढंग से संपादित किया है
जोशारपी

62

आपका नमूना पसिडो कोड जैसा दिखता है। आपको इसका परिणाम वापस करने की आवश्यकता है RedirectToAction:

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

4
यह बताया जाना चाहिए कि यदि लक्ष्य कार्रवाई केवल POST को स्वीकार करती है, तो यह काम नहीं करेगा।
मार्को अल्वेस

13
यह एक 302 देता है जो सर्वर के लिए एक और हिट का कारण बनता है जो सवाल नहीं पूछता है।
रौबर्मन

16

जैसा कि @DLeh कहता है कि उपयोग करें

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

लेकिन, नियंत्रक देना, एक नियंत्रक संदर्भ विशेष रूप से महत्वपूर्ण है जब आपको Userऑब्जेक्ट, Serverऑब्जेक्ट या HttpContextअंदर 'बच्चे' नियंत्रक तक पहुंचने की आवश्यकता होती है ।

मैंने कोड की एक पंक्ति जोड़ी है:

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

या फिर आप सिस्टम का उपयोग कर सकते थे। वर्तमान संदर्भ को भी एक्सेस करने के लिए, Serverया प्रारंभिक मेटियन ऑब्जेक्ट्स को एक्सेस करने के लिए

नायब: मैं फ्रेमवर्क संस्करण 4.6 (Mvc5) को लक्षित कर रहा हूं


4
यदि आप नियंत्रक में एक क्रिया को कॉल करने का प्रयास करते हैं जो दृश्य (..) या आंशिक दृश्य (...) का उपयोग करता है, तो आपको मैन्युअल रूप से रूटडेटा को बदलने की आवश्यकता है, ताकि ASP.NET जानता है कि आपका दृश्य कैसे खोजा जाए। controller.RouteData.Values["controller"] = "Home";controller.RouteData.Values["action"] = "Index";यह मानते हुए कि आप HomeController में सूचकांक कार्रवाई से परिणाम वापस करने की कोशिश कर रहे हैं।
स्टीवन

@ thisइसके बजाय मुझे इन मूल्यों को लागू करना था controller। अंतत: परिणाम स्थानीय नियंत्रक (यह) के माध्यम से वापस आता है, इसलिए वह वही है जो दृश्य को खोजने की कोशिश करता है।
अहांतोइन

मैं यह भी जोड़ना चाहता हूं कि Url संपत्ति DependencyResolver.Current.GetService <ControllerB> () पर आरंभिक नहीं है। तो आपको इसे वर्तमान नियंत्रक से मैन्युअल रूप से कॉपी करना होगा।
राल्फस

लक्ष्यीकरण क्रिया में आपको return View("ViewName");इसके बजाय का उपयोग करना चाहिएreturn View();
mNejkO

9

रिज़ॉल्वर को स्वचालित रूप से ऐसा करने दें।

एक नियंत्रक के अंदर:

public class AController : ApiController
{
    private readonly BController _bController;

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

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

}

2
सबसे साफ जवाब imo, लेकिन आप नियंत्रक संदर्भ को नए नियंत्रक पर सेट करना चाहिए।
माफिया

8

अगर कोई भी यह देख रहा है कि यह कैसे करना है .net कोर मैंने इसे स्टार्टअप में नियंत्रक जोड़कर पूरा किया

services.AddTransient<MyControllerIwantToInject>();

फिर इसे दूसरे कंट्रोलर में इंजेक्ट करते हैं

public class controllerBeingInjectedInto : ControllerBase
{
    private readonly MyControllerIwantToInject _myControllerIwantToInject

     public controllerBeingInjectedInto(MyControllerIwantToInject myControllerIwantToInject)
{
       _myControllerIwantToInject = myControllerIwantToInject;
      }

तो बस इसे कॉल करें _myControllerIwantToInject.MyMethodINeed();


4

यह ठीक वैसा ही है जैसा मैं ढूंढने के बाद देख रहा था कि RedirectToAction()जटिल क्लास ऑब्जेक्ट्स पास नहीं होंगे।

एक उदाहरण के रूप में, मैं नियंत्रक IndexComparisonमें विधि को कॉल करना चाहता हूं LifeCycleEffectsResultsऔर इसे मॉडल नामक एक जटिल वर्ग ऑब्जेक्ट पास करना चाहता हूं ।

यहाँ वह कोड है जो विफल हुआ:

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

ध्यान देने योग्य बात यह है कि स्ट्रिंग्स, पूर्णांक, आदि इस नियंत्रक पद्धति की यात्रा से बच रहे थे, लेकिन जेनेरिक सूची ऑब्जेक्ट सी मेमोरी लीक की याद ताजा कर रहे थे।

जैसा कि ऊपर सुझाया गया है, यहाँ पर मैंने इसका कोड बदल दिया है:

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

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

अभी जैसा इरादा है सब काम कर रहे हैं। रास्ता अग्रणी करने के लिए धन्यवाद।


3

डेल्ह का उत्तर सही है और यह बताता है कि आईओसी के लिए स्थापित निर्भरता के बिना किसी अन्य नियंत्रक का उदाहरण कैसे प्राप्त करें

हालांकि, अब हमें इस अन्य नियंत्रक से विधि को कॉल करने की आवश्यकता है।
पूर्ण उत्तर होगा:

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

//Call your method
ActionInvoker.InvokeAction(controller.ControllerContext, "MethodNameFromControllerB_ToCall");

यदि आप पैरामीटर की अपेक्षा करते हैं तो आप "MethodNameFromControllerB_ToCall" क्रिया को कैसे कहते हैं? उदाहरण के लिए MethodNameFromControllerB_ToCall (int somenum, string someext)?
पाटे गुटी

3

मुझे पता है कि यह पुराना है, लेकिन आप कर सकते हैं:

  • सर्विस लेयर बनाएं
  • वहाँ विधि ले जाएँ
  • दोनों नियंत्रकों में कॉल विधि

2

अगर समस्या कॉल करने की है। आप इस विधि का उपयोग करके इसे कॉल कर सकते हैं।

yourController obj= new yourController();

obj.yourAction();

1
Pfft! यदि आप इसके बजाय एक क्रिया से परिणाम की उम्मीद कर रहे हैं तो क्या होगा? var res = new ControllerB().SetUpTimer(new TimeSpan(23, 20, 00));
डर्टीबिट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.