2009-09-30 16 views
7

È possibile che un controller ASP.NET MVC crei una nuova istanza di un controller diverso e deleghi effettivamente la resonsabilità a tale controller?.NET MVC controller instantiate all'interno di un altro controller

Diciamo ad esempio che ho due controllori in/directory/Controller:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
      var otherController = new OtherController(); 
      return otherController.ShowNumberOfThings(100); 
    } 
} 

public class OtherController : Controller 
{ 
     public ActionResult ShowNumberOfThings(int index) 
     { 
      return View(index); 
     } 
} 

... e una visualizzazione denominata Vista/Altro/ShowNumberOfThings.aspx:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="ViewPage<int>" %> 
Number of things: <%= Model.ToString() %> 

Quando mi ha colpito l'url:

http://localhost/Home/Index

voglio essere presente Ed con una pagina che recita:

"Numero di cose: 100"

Mi piacerebbe essere in grado di persistere dati temporanei tra i reindirizzamenti del controller senza essere costretti ad utilizzare l'oggetto di sessione (TempData [ ""] usi l'oggetto della sessione per i reindirizzamenti del controllore incrociato). Il mio caso reale ha un oggetto complesso che ha bisogno di passare (non solo un int), quindi l'utilizzo di un URL/cookie è fuori questione e lo stato della sessione è un no-no.

In WebForms almeno potremmo utilizzare Server.Transfer e mantenere qualsiasi stato nella raccolta HttpContext.Items. In MVC l'unica opzione che posso vedere è chiamare il metodo controller passando direttamente gli argomenti richiesti.

Al momento non è possibile provare a risolvere la cartella di visualizzazione poiché il "contesto" è ancora in esecuzione in HomeController.

Indovino dove sto andando con questo sta cercando di clandare ASP.NET MVC a comportarsi come un FrontContoller.

Qualche idea?

EDIT

Alla fine abbiamo dovuto puntate tutto in una sessione e l'uso che. Un peccato, ma ho sentito che MVC2 supporterà la serializzazione di oggetti in un ViewState.

+0

Ho fatto qualcosa di molto simile a questo che ha funzionato bene - il modello dovrebbe essere passato correttamente, quindi che cos'è il contesto che è un problema? – Keith

risposta

2

Penso che sarebbe preferibile utilizzare.

return RedirectToAction("Controller", "Action") 

Tuttavia, suppongo che vogliate mantenere l'Url Home/Index. Se si sta osservando il pattern di FrontController, è necessario esaminare la scrittura di una Custom ControllerFactory che eredita da DefaultControllerFactory, quindi Sostituisci il metodo CreateController. Puoi registrare la tua fabbrica usando il codice qui sotto.

protected void Application_Start() 
    { 
     ControllerBuilder.Current.SetControllerFactory(new MyCustomControllerFactory(); 
     RegisterRoutes(RouteTable.Routes); 
    } 

Nella fabbrica Controller hanno accesso al RequestContext in modo da poter cambiare il RouteData come necessario e delegare al controllore corretto.

Si potrebbe ovviamente impostare solo un percorso personalizzato per Casa/Indice che va a OtherController.ShowNumberOfThings()

routes.MapRoute("Home", "Home/Index/{id}", 
          new {controller = "Other", action = "ShowNumberOfThings", id = 100}); 
+1

Non riesco a utilizzare RedirectToAction poiché ciò comporta due richieste HTTP. Nella mia situazione ho bisogno di passare un oggetto complesso, non un int, quindi non posso realmente serializzarlo in un parametro querystring (route). Bella risposta però. – Codebrain

3

Se si desidera essere presentato con "Numero di cose: 100" quando si colpisce l'azione indice perché non rende direttamente la vista corrispondente:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View("~Views/Other/ShowNumberOfThings.aspx", 100); 
    } 
} 
1

un approccio diverso sarebbe l'uso di viste parziali

invece di ~Views/Other/ShowNumberOfThings.aspx

si potrebbe mettere la visualizzazione in ~Views/shared/ShowNumberOfThings.ascx

hanno entrambe le viste ~Views/Other/ShowNumberOfThings.aspx e ~Views/Home/Index.aspx attuare la vista parziale

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
      return View(100); 
    } 
} 

public class OtherController : Controller 
{ 
     public ActionResult ShowNumberOfThings(int index) 
     { 
      return View(index); 
     } 
} 

e in entrambe le viste attuare la vista parziale

<% Html.RenderPartial("~Views/shared/ShowNumberOfThings.ascx", ViewData.Model); %> 

è possibile modificare l'int per qualsiasi oggetto che sarà passato al modello

0

Un'altra possibilità (simile alle viste parziali) è quella di utilizzare Html.RenderAction. Ciò consente diverse classi di modelli di viste e metodi di controllo separati.

<% Html.RenderAction("yourActionName", "yourControllerName", routeValues); %> 
Problemi correlati