2009-09-30 63 views
7

¿Es posible que un controlador MVC de ASP.NET cree una nueva instancia de un controlador diferente y delegue efectivamente la resignificación a eso?.Controlador de instancias de .NET MVC dentro de otro controlador

Digamos por ejemplo que tengo dos controladores en el/Controladores/directorio:

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); 
     } 
} 

... y una vista llamada Vistas/Otros/ShowNumberOfThings.aspx:

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

Cuando golpeé la url:

http://localhost/Home/Index

quiero estar presente ed con una página que dice:

"serie de cosas: 100"

Me gustaría ser capaz de persistir los datos temporales entre cambios de dirección del controlador sin estar obligado a utilizar el objeto de sesión (TempData [ ""] usos el objeto de sesión para las redirecciones de controlador cruzado). Mi caso del mundo real tiene un objeto complejo que necesita pasar (no solo un int), por lo que no se puede usar una URL/Cookie, y el estado de la sesión es un no-no.

En WebForms al menos podríamos usar Server.Transfer y mantener cualquier estado en la colección HttpContext.Items. En MVC, la única opción que puedo ver es llamar al método del controlador que pasa directamente los argumentos requeridos.

Por el momento, tiene problemas para tratar de resolver la carpeta de visualización ya que el "contexto" todavía se está ejecutando bajo HomeController.

Supongo que a dónde voy con esto es tratar de hacer que ASP.NET MVC actúe como un FrontContoller.

¿Alguna idea?

EDITAR

Al final tuvimos que serializar todo en una sesión y usar eso. Una pena, pero he oído que MVC2 admitirá objetos de serialización en un ViewState.

+0

He hecho algo muy similar a esto que funcionó bien: el modelo se debe aprobar correctamente, entonces, ¿qué problema hay en el contexto? – Keith

Respuesta

2

Creo que sería preferible usar.

return RedirectToAction("Controller", "Action") 

Sin embargo, supongo que quiere mantener la URL de Inicio/Índice. Si está mirando el patrón FrontController, debe investigar escribir una Custom ControllerFactory que hereda de DefaultControllerFactory y luego anular el método CreateController. Puede registrar su fábrica utilizando el siguiente código.

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

En la fábrica del controlador que tienen acceso a la RequestContext para que pueda cambiar el RouteData según sea necesario y delegar en el controlador correcto.

Por supuesto, puede simplemente establecer una ruta personalizada para Inicio/Índice que va a OtherController.ShowNumberOfThings()

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

No puedo usar RedirectToAction ya que esto da como resultado dos solicitudes HTTP. En mi situación, necesito pasar un objeto complejo, no un int, por lo que realmente no puedo serializarlo en un parámetro querystring (ruta). Buena respuesta, sin embargo. – Codebrain

3

Si quieres ser presentado con "Número de cosas: 100" cuando se pulse la acción Índice de por qué no hacen directamente la vista correspondiente:

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

un enfoque diferente sería el uso de vistas parciales

en lugar de ~Views/Other/ShowNumberOfThings.aspx

que podría poner su vista en ~Views/shared/ShowNumberOfThings.ascx

tienen ambos puntos de vista ~Views/Other/ShowNumberOfThings.aspx y ~Views/Home/Index.aspx implementan la vista parcial

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

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

y en ambos puntos de vista aplicar la vista parcial

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

puede cambiar el int para cualquier objeto que se pasará a la modelo

0

Otra posibilidad (similar a vistas parciales) es usar Html.RenderAction. Esto permite diferentes clases de modelos de vista y métodos de controlador separados.

Cuestiones relacionadas