Başka bir denetleyici nasıl çağırılır Eylem Mvc'deki bir denetleyiciden


153

Denetleyici A denetleyicisi B eylem FileUploadMsgView çağırmak gerekir ve bunun için bir parametre geçmek gerekir.

 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
Bu sorunun eski olduğunu biliyorum ama bence ed şapelin cevabını en iyisi olarak işaretlemelisin, kravatın bir kesmek gibi görünüyor, hala geçerli, ama neden olması gerektiği gibi kullanabileceğiniz bir geçici çözüm kullanmalısınız ve istenen sonuç elde
Anders M.

1
@AndersM. Ed'in cevabı bir yönlendirme yapar. Bu soruyu bir çözüm ararken bulduğumda istediğim bu değil.
mxmissile

mxmissile bir dick olmamak ama Ed'in cevabı, yüklenene dayanarak geri dönen bir görüş istediği için askerin ihtiyacı olan şeydir, ben askerin sorusunu formüle etmede daha iyi bir iş yapmış olabileceğini kabul ediyorum (bu doğru kelime mi? ) İngilizcesi sınırlı olabileceğinden bunu bilmiyoruz, çünkü Tiesons'un cevabı size yardımcı olmasına rağmen - ki bu iyi - Ed'in cevabının askerin ihtiyaç duyduğu şeyleri en iyi şekilde yansıttığı gerçeğini değiştirmez
Anders M.

2
@AndersM. Benim comment ifadeler ... sadece kötü anlamak :-) ben sonucu olmadığını vurguladık gerekirdi ben arzu.
mxmissile

@AndersM. Asker Tieson'un cevabını en iyi şekilde kabul etti, bu yüzden neden ona karar vereceğinden emin değilim? Tieson'un bana verdiği cevap, Ed'in cevabından daha fazla bana yardımcı oldu. SO, sadece tek bir kişiye değil, benzer sorunları olan herkese yardım etmek içindir. Öyleyse neden sadece Tieson'un cevabını üstte tutmuyorsunuz?
Kevin Voorn

Yanıtlar:


106

Denetleyiciler sadece sınıftır - yeni bir tane ve diğer herhangi bir sınıf üyesinde yaptığınız gibi eylem yöntemini çağırın:

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


76
Bunu yaparsanız ControllerContext, Request ve arkadaşlarınızı kaçırmayacak mısınız?
cirrus

20
Denetleyicinin örneklenmesi iyi bir fikir değildir, çünkü yaşam döngüsü uygulamanın başka bir bölümü tarafından kontrol edilebilir. Örneğin bir IoC konteyneri kullanılırken tüm depresyonlar enjekte edilmelidir, vb.
Mo Valipour

48
IoC kullanıyorsanız,var controller = DependencyResolver.Current.GetService<ControllerB>();
mxmissile

3
@mxmissile Buraya bir yorum yapmak yerine yeni bir yanıt olarak eklemeye değer.
Tieson T.

2
@ilasno "Kontrolün ters çevrilmesi" terimini biliyor musunuz? Yaptığı nokta, denetleyicilerinizde yapıcıya enjekte edilmesi gereken bileşenler varsa, bir servis bulucu olarak DependencyResolver gibi bir şey kullanmadığınız sürece cevabım gerçekten işe yaramaz.
Tieson T.

202

@Mxmissile, kabul edilen cevaba yapılan yorumlarda söylediği gibi, kontrol cihazını yeni başlatmamalısınız, çünkü IoC için ayarlanmış bağımlılıklar eksik olacak ve HttpContext.

Bunun yerine, denetleyicinizin böyle bir örneğini almalısınız:

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

Tam aradığım şey. IoC kullanmayanların yine de HttpContextenjekte edilmeyeceğini unutmayın .
brichins

var controllertürü atanır ControllerB, evet.
DLeh

1
Bu beni yaklaştırıyor, ancak ortaya çıkan bir sorun benim durumumda controller.MyAction () uinstantiated gibi görünen User.Identity referans yapar olmasıdır.
Robert H. Bourdeau

1
@ilasno Bugünlerde MVC paslı değilim, ama ben aslında zorunda anlamına geliyordu düşünüyorum var IoC tam nüfuslu Denetleyici nesneyi almak üzere ayarlanmış (örneğin ilişkili bir HttpContext). Ben bir "sığ" denetleyici nesnesi (sadece bazı işlevselliğe erişim gerekli) almak için herhangi bir IoC olmadan bu yaklaşımı kullandığımı ve başlangıçta neden parçaları "eksik" hakkında karıştı inanıyorum . [kenara: Hala bu yaklaşımı kullanırken etrafında çalıştım, ama muhtemelen bu işlevselliği paylaşılan bir sınıfa yeniden yansıtmış olmalıydım.
brichins

3
Bazı insanlar anlamsız düzenlemelerle taşınır ... birisi "denetleyici" değişkenini "ctrlr" olarak değiştirerek cevabı düzenlediğini unutmayın ... bu yüzden "ctrlr.ControllerContext = new ControllerContext (this.Request.RequestContext, ctrl) ;" kullanıcı doğru düzenlediyse
JoeSharp

62

Örneğiniz psuedo koduna benziyor. Sen gerekir dönmek sonucunu RedirectToAction:

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

4
Hedef eylem sadece POST'u kabul ederse, bunun işe yaramayacağına dikkat edilmelidir.
Marco Alves

13
Bu, 302 döndürür, bu da soruyu soran sunucuya başka bir isabet neden olur.
rboarman

16

@DLeh dediği gibi Kullanım yerine

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

Ancak, denetleyiciyi vermek, özellikle Usernesneye, Servernesneye veya HttpContext'alt' denetleyicinin içine erişmeniz gerektiğinde bir denetleyici bağlamı önemlidir .

Bir kod satırı ekledim:

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

ya da geçerli içeriğe erişmek Server, metionlu nesnelere erişmek ya da erken ölçülen nesnelere erişmek için System.Web'i de kullanabilirsiniz.

Not: 4.6 çerçeve sürümünü (Mvc5) hedefliyorum


4
Denetleyicide View (..) veya PartialView (...) kullanan bir eylem çağırmayı denerseniz, ASP.NET'in görünümünüzü nasıl bulacağını bilmesi için routeData'yı el ile değiştirmeniz gerekir. controller.RouteData.Values["controller"] = "Home";controller.RouteData.Values["action"] = "Index";HomeController'daki Index eyleminden sonucu döndürmeye çalıştığınızı varsayarsak.
Steven

@Steven bu değerleri thisyerine uygulamak zorunda kaldım controller. Sonuçta sonuç yerel denetleyiciden (bu) geri gelir, bu yüzden görünümü bulmaya çalışır.
aaaantoine

Ayrıca Url özelliğinin DependencyResolver.Current.GetService <ControllerB> () üzerine başlatılmadığını da ekleyeceğim. Bu yüzden mevcut denetleyiciden manuel olarak kopyalamanız gerekir.
Ralfeus

Hedefleme return View("ViewName");return View();
Eyleminde

9

Çözümleyicinin bunu otomatik yapmasına izin verin.

A denetleyicisi içinde:

public class AController : ApiController
{
    private readonly BController _bController;

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

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

}

2
en temiz yanıtı imo, ancak denetleyici içeriğini yeni denetleyiciye ayarlamanız gerekir.
Mafii

8

Eğer kimse bunu .net çekirdeğinde nasıl yapacağına bakıyorsa, başlangıçta kontrolörü ekleyerek başardım.

services.AddTransient<MyControllerIwantToInject>();

Sonra diğer denetleyiciye enjekte etmek

public class controllerBeingInjectedInto : ControllerBase
{
    private readonly MyControllerIwantToInject _myControllerIwantToInject

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

O zaman böyle söyle _myControllerIwantToInject.MyMethodINeed();


4

Bu tam olarak RedirectToAction()karmaşık sınıf nesnelerini geçmeyecek bulduktan sonra aradığım şeydi .

Örnek olarak, denetleyicideki IndexComparisonyöntemi çağırmak ve LifeCycleEffectsResultsmodel adında karmaşık bir sınıf nesnesi iletmek istiyorum .

Başarısız olan kod:

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

Dikkat çeken nokta, Dizeler, tamsayılar, vb. Bu denetleyici yöntemine yapılan yolculuktan kurtuldu, ancak genel liste nesneleri C bellek sızıntılarını anımsatan acı çekiyordu.

Yukarıda önerildiği gibi, yerine koyduğum kod:

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

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

Her şey şu anda planlandığı gibi çalışıyor. Yol gösterdiğiniz için teşekkür ederim.


3

Dleh'ın cevabı doğrudur ve IoC için eksik bağımlılıklar olmadan başka bir denetleyicinin örneğini nasıl alacağınızı açıklayın

Ancak, şimdi bu diğer denetleyiciden yöntemi çağırmamız gerekiyor.
Tam cevap:

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

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

Parametreleri beklerse "MethodNameFromControllerB_ToCall" eylemini nasıl çağırırsınız? örneğin MethodNameFromControllerB_ToCall (int somenum, string sometext)?
Patee Gutee

3

Eski olduğunu biliyorum, ama şunları yapabilirsiniz:

  • Hizmet katmanı oluşturma
  • Yöntemi oraya taşı
  • Her iki denetleyicide çağrı yöntemi

2

Sorun aramaksa. bu yöntemi kullanarak arayabilirsiniz.

yourController obj= new yourController();

obj.yourAction();

1
Pfft! Bunun yerine bir işlemden sonuç bekliyorsanız ne olur? var res = new ControllerB().SetUpTimer(new TimeSpan(23, 20, 00));
DirtyBit
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.